Thursday, June 28, 2012

How to update Activity from Service using ResultReceiver

Today I am going to show how can we update Activity using android.os.ResultReceiver. What we need is just create and inner class inside an Activity that extends ResultReceiver and override its onReceiveResult() methods that will be called while sending data from Service class and inside this method we can update UI components.


What I will show in Demo?
I will just create an Activity with a TextView and update the TextView with current seconds of time.


So, create an Activity with main.xml having a TextView. Also, an inner class that extends ResultReceiver and  a class that extends Runnable to be used for runOnUiThread.



public class ResultReceiverDemoActivity extends Activity{

Intent intent;
TextView txtview;
MyResultReceiver resultReceiver;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

resultReceiver = new MyResultReceiver(null);
txtview = (TextView) findViewById(R.id.txtview);
intent = new Intent(this, MyService.class);
intent.putExtra("receiver", resultReceiver);
startService(intent);
}

@Override
protected void onDestroy() {
super.onDestroy();
stopService(intent);
}


class UpdateUI implements Runnable
{
String updateString;

public UpdateUI(String updateString) {
this.updateString = updateString;
}
public void run() {
txtview.setText(updateString);
}
}

class MyResultReceiver extends ResultReceiver
{
public MyResultReceiver(Handler handler) {
super(handler);
}

@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {

if(resultCode == 100){
runOnUiThread(new UpdateUI(resultData.getString("start")));
}
else if(resultCode == 200){
runOnUiThread(new UpdateUI(resultData.getString("end")));
}
else{
runOnUiThread(new UpdateUI("Result Received "+resultCode));
}
}
}
}

As, you can see there is nothing much in the above code just a simple one. The new thing about you would be the class that extends ResultReceiver. It is having an overrided method onReceiveResult(int resultCode, Bundle resultData) with parameters resultCode and Bundle. These two parameters we will pass from the Service class using send(resultCode, Bundle resultData) of ResultReceiver which will be pass to onReceiveResult(int resultCode, Bundle resultData) where we can update the UI.

Also, one more important thing is that you might have seen that I am passing a putExtra to Service class as
intent.putExtra("receiver", resultReceiver); where resultReceiver is the instance of MyResultReceiver class that extends ResultReceiver. We will get the putExtra in the Service class and use the same instance to send data from Service to Activity using send(resultCode, Bundle resultData).


Now, lets add the Service class that is also a simple one having a Timer with 1 second.



public class MyService extends Service{

Timer timer = new Timer();
MyTimerTask timerTask;
ResultReceiver resultReceiver;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

resultReceiver = intent.getParcelableExtra("receiver");

timerTask = new MyTimerTask();
timer.scheduleAtFixedRate(timerTask, 1000, 1000);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
timer.cancel();
Bundle bundle = new Bundle();
bundle.putString("end", "Timer Stopped....");
resultReceiver.send(200, bundle);
}

class MyTimerTask extends TimerTask
{
public MyTimerTask() {
Bundle bundle = new Bundle();
bundle.putString("start", "Timer Started....");
resultReceiver.send(100, bundle);
}
@Override
public void run() {
SimpleDateFormat dateFormat = new SimpleDateFormat("s");
resultReceiver.send(Integer.parseInt(dateFormat.format(System.currentTimeMillis())), null);
}
}
}

So, simply we are getting the putExtra of ResultReceiver's instance using resultReceiver = intent.getParcelableExtra("receiver"); inside onStartCommand() to use it further for sending the data to Activity. You can send any data to Activity using send(resultCode, Bundle resultData) method of ResultReceive, you can send an error message also with the same method checking the resultCode.
Source code can be found here.

14 comments:

  1. Thanks for the tute. Could you please explain why you would use this method instead of Handlers and Messages?

    ReplyDelete
    Replies
    1. Yes, agree with El Niño, your tutorial is Pretty good.

      If one needs to use the Handler <-> Message way to achieve the same goal, then here it goes:

      ----
      In your UI Class, you must define another nested static class which extends the Handler Class, like:

      public static class TestHandler extends Handler
      {
      @Override
      public void handleMessage(Message msg)
      {
      super.handleMessage(msg);
      switch(msg.what) // msg.what is an identifier (int)
      {
      // Do your stuff for each message received
      }
      }
      }

      Then, in your Service Class, you instantiate that static class as a Handler:
      (You can use the specific class, like: MyUI.TestHandler, or you can just do a simple Uppercast to use a Handler in a straightforward manner.)

      Like:

      public class BackgroundService extends Service
      {

      @Override
      public int onStartCommand(Intent intent, int flags, int startId)
      {
      Handler hand = new MyUI.TestHandler();

      Message msg = new Message();
      msg.what = MyUI.sServAtivo; // 1
      hand.sendMessageDelayed(msg, 4000); // Just to have to wait

      return super.onStartCommand(intent, flags, startId);
      }

      @Override
      public IBinder onBind(Intent arg0)
      {
      return null;
      }

      }

      ---


      Just bear in mind:
      If you do it this way, you cannot directly access UI components, "only the UI can touch its views" someone may say. If you need to, you'll have to implement some listeners or, maybe, extend your UI activity and implement the changes inside another Thread.

      Delete
  2. It is really a great work and the way in which u r sharing the knowledge is excellent.Thanks for helping me to understand basic concepts. As a beginner in android programming your post help me a lot.Thanks for your informative article. Best Android Training in chennai

    ReplyDelete
  3. This is a wonderful article, Given so much info in it, These type of articles keeps the users interest in the website, and keep on sharing more ... good luck.
    Android Training in chennai | Android Training

    ReplyDelete
  4. These ways are very simple and very much useful, as a beginner level these helped me a lot thanks fore sharing these kinds of useful and knowledgeable information.
    Mobile App Development Company in Chennai
    Android app Development Company in Chennai
    ios app development Company in Chennai

    ReplyDelete
  5. Wow, I have gone through the written program and I have reminded myself the basic programming skills and knowledge I learned while in college. I will save this page so that I can go though the program slowly and understand the syntax. Apart from loving to program, I write articles and m articles can be read by clicking on How to Develop Good Research Writing Skills.

    ReplyDelete
  6. Marvelous site all content was very quality and I'm seeing the most of the content is really well.Great article.
    Selenium Training in Chennai
    Best Selenium Training Institute in Chennai
    Selenium Training in Chennai

    ReplyDelete

  7. I am expecting more interesting topics from you. And this was nice content and definitely it will be useful for many people.

    Android App Development Company

    ReplyDelete
  8. Even though we can claim that we can generate our own ideas and use them to develop our own projects, secondary sources are also very useful. There is that kind of information which you will only obtain by reading such articles. this is the kind of information which I daily desire to have. Ask for Supply Chain Management Homework Help from experts.

    ReplyDelete
  9. Nice it seems to be good post... It will get readers engagement on the article since readers engagement plays an vital role in every blog.i am expecting more updated posts from your hands.
    iOS App Development Company

    ReplyDelete
  10. I wondered upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I’ll be subscribing to your feed and I hope you post again soon.

    Fitness SMS
    Fitness Text
    Salon SMS
    Salon Text
    Investor Relation SMS
    Investor Relation Text

    ReplyDelete
  11. great and nice blog thanks sharing..I just want to say that all the information you have given here is awesome...Thank you very much for this one.
    web design Company
    web development Company
    web design Company in chennai
    web development Company in chennai
    web design Company in India
    web development Company in India

    ReplyDelete