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.
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.