2011-11-18 38 views
6

Tôi đang phát triển một ứng dụng Android và tôi có một nút khởi động/tạm dừng quá trình mô phỏng nhất định. Trong khi quá trình này đang chạy, tôi cần xuất dữ liệu từ thời gian thực. Nhưng khi tôi tạo một luồng mới cho mô phỏng, tôi không thể truy cập các khung nhìn (để nó là TextView) từ luồng này, bởi vì chúng chỉ có thể được truy cập từ luồng mà chúng được tạo ra. Mặt khác, chủ đề mới là cần thiết bởi vì nếu không người dùng sẽ không thể làm bất cứ điều gì trong khi mô phỏng đang chạy (ví dụ, nhấn một số nút khác). Tạo một dịch vụ mới cũng yêu cầu tạo một luồng mới trong trường hợp này. Tôi nên giải quyết vấn đề này như thế nào?Truy cập các giao diện từ chủ đề khác (Android)

+0

Bạn đã kiểm tra ra [ 'AsyncTask'] (http: // nhà phát triển .android.com/reference/android/os/AsyncTask.html) lớp học? Đây là một lớp tiện ích giúp bạn tạo một luồng khác dễ dàng và cập nhật các phần tử giao diện người dùng tương ứng. Bạn có thể sử dụng phương thức 'publishProgress()' và 'onProgressUpdate()' trong trường hợp này. –

Trả lời

5

Bạn có thể xử lý nó bằng nhiều cách,

  1. Cố gắng sử dụng AsyncTask trong này, công việc nền của bạn thực hiện trong doInBackGround() phương pháp, và giao diện người dùng của bạn sẽ không chặn và bạn cũng có thể truy cập chế độ xem Hoạt động từ nơi bạn gọi AsyncTask theo ngữ cảnh của nó qua publishProgress() và onProgressUpdate().

  2. Nếu bạn đang sử dụng một đơn giản Chủ đề sau đó sử dụng Handler hoặc tin nhắn hoặc runOnUiThread bạn có thể cập nhật quan điểm của chủ đề chính.

nhưng, in your way I think AsyncTask is best for you.

2

Bạn có thể giải quyết sự cố với android.os.Handler. Trường hợp trình xử lý được gắn kết với luồng tạo ra nó, bạn có thể đăng Runnables đến nó và nó sẽ thực thi chúng trong luồng mà nó được ràng buộc. Ví dụ:

import android.os.Handler; 
import android.widget.TextView; 

public class MyActivity extends Activity { 
    private Handler uiHandler; 
    private TextView simulationStatus; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    ... 
    uiHandler = new Handler(); 
    ... 
    simulationStatus = (TextView) findViewById(R.id.simulationStatus); 
    ... 
    } 

    // This method is to be executed on the simulation thread. 
    public void simulate() { 
    ... 
    final String simulationStatusText = ...; 
    ... 
    uiHandler.post(new Runnable() { 
     @Override 
     public void run() { 
     // This is run on the UI thread. 
     simulationStatus.setText(simulationStatusText); 
     ... 
     } 
    }); 
    } 

    ... 
} 

Bạn cũng có thể sử dụng AsyncTask. Xem liên kết ví dụ.

1

Chuyển hoạt động tới chuỗi của bạn và sử dụng nó từ bên trong để truy cập vào chế độ xem của bạn.

// from your activity: 
myExternalThread = new MyCustomCode(this); // <-- activity passed 

// your "simulation process" constructor: 
public MyCustomCode(Activity parent) { 
    this.parent = parent; 
} 

// and when you want to access views: 
parent.runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     parent.findViewById(R.id.text_view); 
     ... do something to your UI ... 
    } 
}); 

cách ưa thích của tôi về việc tạo ra những công việc bên ngoài là sử dụng AsyncTask (sau đó bạn không phải lo lắng về runOnUiThread, trong số những lợi ích khác). Tôi không biết nếu nó áp dụng cho trường hợp của bạn, nhưng bạn nên kiểm tra xem nó ra.

+0

Tại sao -1?Có lời giải thích nào không? – Guillaume

1

bạn phải lưu trữ dữ liệu mà bạn đang muốn làm hiển thị thành một var công cộng và để cho chủ đề của bạn gọi một Runnable qua Handler.post (Runnable) Mã trong thời gian() phương pháp của Runnable có thể truy cập vào Textview

2

Chúng có thể được truy cập nhưng chỉ đọc. Ý của bạn là bạn muốn kích hoạt các thay đổi từ một chuỗi trên các khung nhìn. Từ chuỗi công nhân (không phải giao diện người dùng) những thay đổi này không thể được kích hoạt, bạn cần sử dụng .runOnUiThread() hoặc sử dụng Handlers. Sử dụng các tại điểm mà bạn muốn hiển thị một cái gì đó, ví dụ như cập nhật các TextView trong .runOnUiThread(),

Ví dụ:

myThread = new Thread() 
     { 

      @Override 
      public void run() { 
       //yourOperation 
       MyActivity.this.runOnUiThread(new Runnable(){ 

        @Override 
        public void run() { 
         if(e!=null) 
         { 
          myTextView.setText("something"); 
         } 

        }}); 
       super.run(); 
      } 
     }; 
     myThread.start(); 
+0

là nó thực sự có thể chỉ đọc một cái nhìn từ một sợi không ui như bạn đã đề cập? Tôi quan tâm đến việc đọc một Bitmap trên một khung nhìn bằng cách sử dụng bitmap drawingCache = view.getDrawingCache() nhưng tôi tiếp tục nhận được ngoại lệ: CalledFromWrongThreadException: Chỉ chủ đề ban đầu đã tạo ra một hệ thống phân cấp khung nhìn mới có thể chạm vào các khung nhìn của nó. – Giorgio

Các vấn đề liên quan