本文共 6997 字,大约阅读时间需要 23 分钟。
Android服务的启动方式与跨进程通信
Android服务作为后台程序运行,能够在没有用户界面的情况下执行任务。与普通应用程序不同,服务可以通过bind和start两种方式启动,它们的运行机制和使用场景有显著区别。本文将详细介绍Android服务的启动方式以及Messenger跨进程通信的实现方法。
服务的启动方式
Android服务可以通过两种方式启动:bind和start。bind方式需要绑定到服务,直到最后一个绑定的程序调用unbind,否则服务会持续运行。而start方式则是启动服务后,需要手动调用stopSelf或stopService来停止服务的运行。
服务的声明周期与启动方式
服务的声明周期可以通过附图了解清楚。需要注意的是,onCreate方法仅在服务第一次启动时调用一次,后续启动时会直接进入onStartCommand或onBind方法。
服务启动方式的代码示例
以下是启动服务的代码示例:
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private boolean hasBound; private Button intent_Service; private Button start_Service; private Button bind_Service; private Button messenger_Service; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 322) { Toast.makeText(getApplicationContext(), "receive message from server", Toast.LENGTH_SHORT).show(); } } }; private Messenger clientMessenger = new Messenger(handler); private Messenger serverMessenger; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { intent_Service = (Button) findViewById(R.id.intent_service); intent_Service.setOnClickListener(this); start_Service = (Button) findViewById(R.id.start_service); start_Service.setOnClickListener(this); bind_Service = (Button) findViewById(R.id.bind_service); bind_Service.setOnClickListener(this); messenger_Service = (Button) findViewById(R.id.messenger_service); messenger_Service.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.intent_service: Intent intentService = new Intent(this, IntentTestService.class); startService(intentService); break; case R.id.start_service: Intent startService = new Intent(this, NormalService.class); startService(startService); break; case R.id.bind_service: Intent bindService = new Intent(this, NormalService.class); if (bindService.resolveActivity(getPackageManager()) != null) { bindService(bindService, connection, Context.BIND_AUTO_CREATE); } break; case R.id.messenger_service: if (!hasBound) { Intent intent = new Intent("com.skateboard.serverservice.service.BIND"); intent.setPackage("com.skateboard.serverservice"); bindService(intent, messengerConnection, Context.BIND_AUTO_CREATE); } else { sendMessageToServier(); } break; } } private ServiceConnection messengerConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { hasBound = true; serverMessenger = new Messenger(service); Message message = new Message(); message.what = 233; message.replyTo = clientMessenger; try { serverMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { hasBound = false; } }; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { NormalService.NormalBinder binder = (NormalService.NormalBinder) service; binder.bindMethod(); } @Override public void onServiceDisconnected(ComponentName name) { } }; private void sendMessageToServier() { Message message = new Message(); message.what = 233; message.replyTo = clientMessenger; try { serverMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onDestroy() { super.onDestroy(); }} 服务的实现类
以下是服务的实现类代码:
public class IntentTestService extends IntentService { public IntentTestService() { super("IntentTestService"); } @Override protected void onHandleIntent(Intent intent) { System.out.println("intent service start"); }} public class NormalService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("service start"); stopSelf(); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { NormalBinder normalBinder = new NormalBinder(); return normalBinder; } @Override public void onDestroy() { super.onDestroy(); System.out.println("stop service"); } public class NormalBinder extends Binder { public void bindMethod() { System.out.println("bind method"); } }} 跨进程通信的实现
跨进程通讯的方式主要有两种:AIDL和Messenger。AIDL是基于消息队列实现的多线程通讯,而Messenger则是基于消息队列实现的单线程通讯。以下是使用Messenger实现跨进程通讯的代码示例:
public class ServerService extends Service { private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 233) { Messenger clientMessenger = msg.replyTo; Message message = new Message(); message.what = 322; try { clientMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } } }; private Messenger messenger = new Messenger(handler); @Override public void onCreate() { super.onCreate(); System.out.println("service create"); } @Override public IBinder onBind(Intent intent) { System.out.println("bind service"); return messenger.getBinder(); }} 跨进程通讯的客户端实现
private ServiceConnection messengerConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { hasBound = true; serverMessenger = new Messenger(service); Message message = new Message(); message.what = 233; message.replyTo = clientMessenger; try { serverMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { hasBound = false; }}; 跨进程通讯的实现流程
通过上述方法,可以实现跨进程通讯,适用于需要在不同进程之间传递消息和数据的场景。
转载地址:http://jbls.baihongyu.com/