2010-07-19 15 views
43

Tôi gặp sự cố với lỗi sau đây trong Android:CalledFromWrongThreadException: Chỉ có chủ đề ban đầu đã tạo ra phân cấp hình ảnh có thể chạm vào quan điểm

CalledFromWrongThreadException ;: Chỉ thread ban đầu đã tạo ra một hệ thống phân cấp xem có thể chạm quan điểm của nó

Dường như điều này xảy ra khi tôi cố gắng cập nhật Textview trong Hoạt động của tôi, cuộc gọi cập nhật TextView là từ trong Hoạt động của tôi nhưng tôi vẫn gặp lỗi trên.

tôi có nó như thế này:

onCreate() -sets lên các nút và xem văn bản.

onStateChange() - người nghe thông báo về thay đổi trạng thái, khi điều này nhận được thông báo nếu thay đổi TextView để nói một số văn bản khác.

Khi tôi nhận được thông báo của một văn bản mới tôi cố gắng thay đổi TextView như vậy:

((TextView)findViewById(R.id.title)).setText("Some Text"); 

Nhưng tôi nhận được lỗi trên.

Từ googling nó, có vẻ như tôi nên sử dụng một trình xử lý để thay đổi TextView hoặc có thể sử dụng AsyncTask?

Có ai có thể giải thích cái nào sẽ tốt hơn để sử dụng và tại sao không?

EDIT: GIA TĂNG đoạn mã:


 public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 

      setContentView(R.layout.my); 

      getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_title); 

      ((TextView)findViewById(R.id.time)).setText("Hello Text"); 


      findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() { 
       public void onClick(View v) { 

        Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:")); 
        startActivity(dialIntent); 

         dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD)); 
         dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));  
       } 
     }); 

    } 

//CallBacks from running Service 

private final ICallDialogActivity.Stub iCallDialogActivity = new ICallDialogActivity.Stub(){ 

@Override 
public void onStateChanged(int callState) 
       throws RemoteException {  
      switch(callState){ 
      case GlobalData.CALL_STATUS_IDLE: 

       break; 

      case GlobalData.CALL_STATUS_DISCONNECTING: 
       byeSetup(); 
       break; 
    } 

}; 

public void byeSetup(){ 

      ((TextView)findViewById(R.id.time)).setText("Bye Text"); 

      findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() { 
       public void onClick(View v) { 
        //Void the Button 
       }}); 
} 
+1

bạn có thuộc lớp con không? onStateChange bị ghi đè ở đâu? – Pentium10

+0

Xin chào Pentium10, nó được ghi đè thông qua giao diện AIDL và giao tiếp với Dịch vụ, Dịch vụ sẽ được thông báo về một số thay đổi và sau đó sẽ thông báo cho Hoạt động cập nhật TextView của nó dựa trên đó. Tôi đã thêm đoạn mã để chứng minh tốt hơn những gì tôi đang cố gắng, Lỗi dường như xuất hiện rất ngẫu nhiên và xuất hiện cả khi Hoạt động ở tiền cảnh và không xuất hiện. –

+1

có thể trùng lặp của [CalledFromWrongThreadException] (http://stackoverflow.com/questions/3413544/calledfromwrongthreadexception) – jww

Trả lời

69

Look như bạn đang ở trên thread sai. Hãy thử sử dụng Trình xử lý để cập nhật GUI trên đúng chuỗi. Xem ví dụ Handling Expensive Operations in the UI Thread từ android.com. Về cơ bản bạn sẽ quấn byeSetup trong một Runnable và gọi nó với một ví dụ Handler.

Handler refresh = new Handler(Looper.getMainLooper()); 
refresh.post(new Runnable() { 
    public void run() 
    { 
     byeSetup(); 
    } 
}); 
+5

Có vẻ như tôi không phải giết tôi. * Phew * –

2

Đối với những người khác, chỉ cần thay thế byeSetup(); với các câu lệnh hoặc phương thức mã của bạn. byeSetup() là một phương thức mẫu. Hy vọng nó sẽ tiết kiệm một số thời gian của bạn.

3

Mở rộng về câu trả lời của willcodejavaforfood cho rõ ràng & thực hiện ...

tôi để làm việc này và dưới đây là cách tôi đã làm nó. Tôi đang chạy nhiều luồng xử lý trong một Dịch vụ để các giải pháp khác chạy trong Hoạt động không hoạt động, như runOnUiThread (Runnable mới() {} ...

Đặt này ở phía trên cùng của lớp dịch vụ của bạn để nó có thể truy cập ở khắp mọi nơi trong lớp này:

Handler handler; 

Đặt này trong lớp dịch vụ phương pháp hoặc cái gì đó nạp vào chủ đề chính Dịch vụ onCreate của bạn

handler= new Handler(Looper.getMainLooper()); 

Đặt mã này bên trong chuỗi bổ sung của bạn vào mã 'đăng lại' để chạy trong giao diện người dùng hoặc giao diện người dùng dịch vụ (whatevers):

handler.post(new Runnable() { 
    public void run() { 
     playNext(); //or whatever method you want to call thats currently not working 
    } 
}); 
0

cách tiếp cận khác, thời gian tận dụng này android.os.Message

đã android.os.Handler định nghĩa là một lĩnh vực trong phạm vi hoạt động của bạn:

private final Handler myTextHandler = new Handler(new Handler.Callback() { 
    @Override 
    public boolean handleMessage(Message stringMessage) { 
     textView.append((String) stringMessage.obj); 
     return true; 
    } 
}); 

Sau đó nuôi nó từ chủ đề khác của bạn như thế này:

Message stringMessage = Message.obtain(myTextHandler); 
stringMessage.obj = "Hello!"; 
stringMessage.sendToTarget(); 
1
     runOnUiThread(new Runnable() { 
          @Override 
          public void run() { 

           // TODO your Code 
           et_Pass.setText(""); 
          } 
         }); 
Các vấn đề liên quan