从服务启动的线程访问活动的实例变量

时间:2014-06-16 17:58:34

标签: android multithreading service handler

在服务中启动一个线程,并尝试使用处理程序更新线程中的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;
            }
        }   
    };  

}

Myservice.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);
    }

2 个答案:

答案 0 :(得分:0)

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

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

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

在您的MainActivity代码中(假设您的主要活动中已定义为类成员的处理程序),在处理程序的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/)。与处理程序相比,使用asynctask更容易,因为它使程序员的生活相对容易一些。希望这些信息有所帮助。

答案 1 :(得分:0)

Handler处理程序= new Handler(getMainLooper());在Service代码中可能是一个与Activity处理程序不同的处理程序实例(Handler mhandler = new Handler())。如何将处理程序从Activity传递给service.See我的新答案。 例如假设有一个名为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);

这应该是理想的。