Android 实践Activity与Service通信
2015-03-30 13:13
281 查看
在MainActivity中启动一个Service,Service中开启一个倒计时,在CountDownActivity中获取倒计时信息并更新UI。通过Binder实现Service与Activity的通信。
1.CountDownService
倒计时信息能被Activity收到是通过回调实现的。接口OnCountDownListener,需要在接收倒计时信息的Activity中实现,以获得倒计时的开始、进行、结束。
2.MainActivity
bindService()中需要传递一个ServiceConnection对象,通过其中的onServiceConnected()拿到Service中的Binder,本例中在通过Binder获取到Service实例。
点击开始按钮,其中倒计时,并打开一个新的Activity,在这个Activity中根据倒计时更新UI。
3.CountDownActivity
这个Activity实现OnCountDownListener接口,实现那三个方法,就可以在相应的方法里更新UI了。
onCreate中对bindService的调用应该是异步的,所以不能够立即建立service连接已获取得到绑定结果。也就是说不能在onCreate的bindService后紧接着执行绑定后的结果,这个时候service对象还没有被获取到,是一个空的。绑定后要执行的方法应该写在onServiceConnected里面。
1.CountDownService
import android.app.Service; import android.content.Intent; import android.content.ServiceConnection; import android.os.Binder; import android.os.CountDownTimer; import android.os.IBinder; public class CountDownService extends Service{ private MyBinder myBinder = new MyBinder(); private OnCountDownListener onCountDownListener; private MyCountDownTimer cdTimer; private int min = 60; private boolean stopped = true; public void setOnCountDownListener(OnCountDownListener onCountDownListener) { this.onCountDownListener = onCountDownListener; } <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 倒计时是否停止 <span style="white-space:pre"> </span> * @return <span style="white-space:pre"> </span> */ public boolean isStopped() { return stopped; } @Override public void onCreate() { super.onCreate(); } @Override public IBinder onBind(Intent arg0) { return myBinder; } @Override /** * 为重新绑定是能调用该生命周期,onUnbind()需要返回return true; */ public void onRebind(Intent intent) { System.out.println("CountDownService.onRebind()"); super.onRebind(intent); } @Override public boolean onUnbind(Intent intent) { System.out.println("CountDownService.onUnbind()"); return super.onUnbind(intent); } @Override public void unbindService(ServiceConnection conn) { System.out.println("CountDownService.unbindService()"); super.unbindService(conn); } <span style="white-space:pre"> </span>/** <span style="white-space:pre"> </span> * 开始倒计时 <span style="white-space:pre"> </span> */ public void startCountDown(){ cdTimer = new MyCountDownTimer(min * 1000, 1000); cdTimer.start(); stopped = false; if(onCountDownListener != null)onCountDownListener.onStartCountDown(); } private class MyCountDownTimer extends CountDownTimer{ public MyCountDownTimer(long millisInFuture, long countDownInterval) { super(millisInFuture, countDownInterval); } @Override public void onFinish() { if(onCountDownListener != null)onCountDownListener.onStopCountDown(); stopped = true; cdTimer.cancel(); } @Override public void onTick(long arg0) { if(onCountDownListener != null)onCountDownListener.onProgress((int)arg0 / 1000); } } public class MyBinder extends Binder{ public CountDownService getService(){ return CountDownService.this; } } public interface OnCountDownListener{ public void onStartCountDown(); public void onProgress(int cd); public void onStopCountDown(); } @Override public void onDestroy() { cdTimer.cancel(); stopSelf(); super.onDestroy(); } }内部类MyBinder继承自Binder,只有一个方法,就是获取到当前CoundDownService实例。
倒计时信息能被Activity收到是通过回调实现的。接口OnCountDownListener,需要在接收倒计时信息的Activity中实现,以获得倒计时的开始、进行、结束。
2.MainActivity
import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { private Button bnStart; private CountDownService cdService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.bn_bind).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { bindService(new Intent(MainActivity.this, CountDownService.class), svcConn, Context.BIND_AUTO_CREATE); bnStart.setEnabled(true); } }); findViewById(R.id.bn_unbind).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { unbindService(svcConn); bnStart.setEnabled(false); } }); bnStart = (Button) findViewById(R.id.bn_start); bnStart.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if(cdService.isStopped()){ cdService.startCountDown(); } else{ Toast.makeText(MainActivity.this, "cd has started", Toast.LENGTH_SHORT).show(); } startActivity(new Intent(MainActivity.this, CountDownActivity.class)); } }); } private ServiceConnection svcConn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { cdService = ((CountDownService.MyBinder)service).getService(); } }; @Override protected void onDestroy() { unbindService(svcConn); cdService.onDestroy(); super.onDestroy(); }; }界面主要就是3个按钮,一个绑定,一个解除绑定,一个开始Service中的倒计时。
bindService()中需要传递一个ServiceConnection对象,通过其中的onServiceConnected()拿到Service中的Binder,本例中在通过Binder获取到Service实例。
点击开始按钮,其中倒计时,并打开一个新的Activity,在这个Activity中根据倒计时更新UI。
3.CountDownActivity
import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.example.demo_servicebinder.CountDownService.OnCountDownListener; public class CountDownActivity extends Activity implements OnCountDownListener{ private TextView tv; private CountDownService cdService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_count_down); tv = (TextView) findViewById(R.id.tv_cd); Intent intent = new Intent(this, CountDownService.class); bindService(intent, svcConn, Context.BIND_AUTO_CREATE); } private ServiceConnection svcConn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { cdService = ((CountDownService.MyBinder)service).getService(); cdService.setOnCountDownListener(CountDownActivity.this); } }; @Override public void onStartCountDown() { Toast.makeText(this, "start", Toast.LENGTH_SHORT).show(); } @Override public void onProgress(int cd) { tv.setText(cd + "秒后结束"); } @Override public void onStopCountDown() { Toast.makeText(this, "onstop", Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy() { unbindService(svcConn); super.onDestroy(); } }首先,需要绑定已经启动的Service,得到CountDownService。
这个Activity实现OnCountDownListener接口,实现那三个方法,就可以在相应的方法里更新UI了。
onCreate中对bindService的调用应该是异步的,所以不能够立即建立service连接已获取得到绑定结果。也就是说不能在onCreate的bindService后紧接着执行绑定后的结果,这个时候service对象还没有被获取到,是一个空的。绑定后要执行的方法应该写在onServiceConnected里面。
相关文章推荐
- Android之Activity与Service通信
- Android:Activity和Fragment生命周期实践
- Android mvp+retrofit+rxjava 编程实践(一)--BaseActivity
- [Android新手学习笔记10]-活动Activity实践之启动、销毁、数据
- Android Activity 和 Fragment 状态保存与恢复的最佳实践
- Android之Activity与Service通信
- Android开发实践 巧用Activity和Fragment
- Android四大控件之Activity详解:实践篇
- android Activity和Fragment生命周期实践
- Android之Activity与Service通信
- android:process结合activity启动模式的一次实践
- Android MVP 实践 Dagger + activity/fragment + viewDelegate
- Android之Activity与Service通信
- Android:Activity和Fragment生命周期实践
- android应用开发实践三----Atcity 通过Intent 来启动另一个Activity来实现简易拨号
- Android学习实践:2.创建另一个Activity并通过按钮单击打开
- [译]Android Activity 和 Fragment 状态保存与恢复的最佳实践
- Android之Activity与Service通信
- [译]Android Activity 和 Fragment 状态保存与恢复的最佳实践
- Android之Activity与Service通信