【问题标题】:Access instance variables of activity from a thread started by a service从服务启动的线程访问活动的实例变量
【发布时间】:2014-06-16 17:58:33
【问题描述】:

在服务中启动一个线程并尝试使用处理程序更新线程中的 UI。我可以使用 getMainLooper 在子线程中定义一个处理程序吗?

MainActivity.java:

public class MainActivity extends Activity {  

    ... 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        btn.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                it=new Intent(getApplicationContext(), Myservice.class);
                startService(it);
            }

        });
    }

    Handler mhandler= new Handler(){         
        public void handleMessage(Message msg){
            switch(msg.what){
            case 1:
                edt.setText("Service");
                break;
            }
        }   
    };  

}

我的服务.java:

public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO Auto-generated method stub

        Thread thread = new Thread(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                Handler handler=new Handler(getMainLooper());
                Message msg = Message.obtain(handler, 1);
                handler.sendMessage(msg);
            }
        });
        thread.start();
        return super.onStartCommand(intent, flags, startId);
    }

【问题讨论】:

    标签: android multithreading service handler


    【解决方案1】:

    Handler handler=new Handler(getMainLooper());服务代码中的处理程序实例可能与活动处理程序不同(Handler mhandler= new Handler())。如何将处理程序从 Activity 传递给服务。请参阅我的新答案。 例如假设有一个名为 MYService 的类:

     public Myservice extends Service  {
    
       private Handler acitivityHandler;
    
       public MyService(Handler handler) {
    
          this.activityHandler =  handler;
    
       }
    
     } 
    

    在调用服务时从您的活动中传入活动的处理程序实例 而不是依赖主循环器。

     Handler mhandler= new Handler(){         
        public void handleMessage(Message msg){
            switch(msg.what){
            case 1:
                edt.setText("Service");
                break;
            }
        }   
    };  
    MyService myService  =  new MyService(mhandler);
    

    这应该很理想。

    【讨论】:

      【解决方案2】:

      不要从(非 UI/主线程)访问 UI 元素,而是从主活动中定义的处理程序访问它们。

      从(非 UI/主线程)继续向处理程序发布事件以进行 UI 更新。

      //Inside the Thread's run method
      public void run() {
          if(uiNeedsToBeUpdated) {
              handler.sendMessage(updateData);
          }
      }
      

      在您的 MainActivity 代码中(假设您在主 Activity 中将一个处理程序定义为类成员),在处理程序的 handleMessage() 中,根据后台任务中的进度更新 UI。

      public void handleMessage (Message msg) {
          switch(msg.getData().getInt("update")) {
              //assuming you've bundled up int from the sending end 
              case 0 : { // background processing started, update UI
                  editText.setText("started");
                  break; 
              }
              case 1 : { // background processing  in progress, update UI
                  editText.setText("In progress");
                  break; 
              }
              case 2:  {  //background processing finished , update UI
                  editText.setText("Done");
                  break;
              }
          }
      }
      

      您还可以使用 Asyntask 代替处理程序 (http://examples.javacodegeeks.com/android/core/os/asynctask/android-asynctask-example/)。与处理程序相比,使用异步任务更容易,因为它使程序员的生活相对容易一些。希望这些信息对您有所帮助。

      【讨论】:

      • 我一开始就是这么做的。但是主要活动中定义的处理程序没有反应。这对你有用吗?我有点认为主活动中定义的处理程序和您在服务中使用 getMainLooper 获得的处理程序是两个不同的处理程序,它们绑定到同一个循环器(主循环器)。所以我们有两个处理程序实例。我不知道这是不是真的。
      • 理想情况下,在您的主要活动中定义的 hadnler 应该已经做出反应。您是如何将处理程序实例传递给 Thread 实例的?能否分享代码。
      • 也可以尝试用 dispatchMessage() 代替 sendMessage(),有时这样可以。
      • 我附上了我在 mainactivity 中定义的处理程序代码。谢谢。
      • 事实上,如果您可以共享整个代码会更容易。谢谢
      猜你喜欢
      • 2011-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多