android中Activity与service之间相互通信的实现方式
16lz
2021-01-23
- 使用intent代参,intent可以带基础数据类型,基础数据类型的数组,序列化对象,集合
- 使用广播
- 使用单例模式,在activity与service中少用
- bindService获取引用,AIDL(进程中通信)基础,推荐使用
activity生命周期
下面是代码:
MainActivity
public class MainActivity extends AppCompatActivity { MyService myservice; private static MainActivity instance; //静态的他一直持有MainActivity的引用,activity是不会退的,也就是程序都退出了,这个引用还在里面,会造成内层泄露 //activity和service都少用单例模式 public static MainActivity getInstance() { return instance; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); instance = this; IntentFilter filter = new IntentFilter("activity"); //上面的activity是用来过滤的service发送广播中所用的intent registerReceiver(receiver, filter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(receiver); unbindService(conn); } public void myIntent(View v) { Intent intent = new Intent(this, MyService.class); intent.putExtra("msg", "activity向service传参用intent方式:hello service"); startService(intent); } public void guangbo(View v) { sendBroadcast(new Intent("service").putExtra("msg", "你好,服务器")); } BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.e("TAG", "接收到Service发来的广播" + intent.getStringExtra("msg")); } }; public void danli(View v) { //必须保证service不能为空 //静态变量,最后释放,不用的时候要手动的将static变量=null; if (MyService.getInstance() != null) { MyService.getInstance().print("activity调用service中的单例"); } } //使用BiandService public void bind(View v) { bindService(new Intent(this, MyService.class), conn, BIND_AUTO_CREATE); } ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //这边的IBinder就是MyService中的onBind 中return的那个IBinder MyService.MyBind bind = (MyService.MyBind) service; myservice = bind.getService();//拿到我们的MyService } @Override public void onServiceDisconnected(ComponentName name) { } }; public void send(View v){ myservice.startMusic(); }}
自己定义的MyService类
public class MyService extends Service { private static MyService instance; public static MyService getInstance() { return instance; } @Nullable @Override public IBinder onBind(Intent intent) { return new MyBind();//这里不能return this 是应为Service不是IBinder的子类,需要自己定义 } class MyBind extends Binder{ public MyService getService(){ return MyService.this;//内部类使用外部类的引用,把service返回回去 } } public void startMusic(){ //随便写一个方法 Toast.makeText(this,"音乐开始播放",Toast.LENGTH_SHORT).show(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { //service接受activity用intent方式传来的参数 String msg = intent.getStringExtra("msg"); Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show(); return super.onStartCommand(intent, flags, startId); } @Override public void onCreate() { super.onCreate(); //注册广播 IntentFilter filter = new IntentFilter("service"); registerReceiver(receiver, filter); instance = this; } @Override public void onDestroy() { super.onDestroy(); //解绑广播 unregisterReceiver(receiver); } BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.e("TAG", "接收到activity发来的广播" + intent.getStringExtra("msg")); sendBroadcast(new Intent("activity").putExtra("msg", "发送给activity的消息")); } }; public void print(String msg) { Log.e("TAG", msg); }}
Layout布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.servicesendactivity_11_10.MainActivity"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="myIntent" android:text="intent传参" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="guangbo" android:text="广播传参" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="danli" android:text="单例模式" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="bind" android:text="绑定service" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="send" android:text="使用service实例调用方法" />LinearLayout>
最后不要忘记要在Androidmanifest中注册
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.servicesendactivity_11_10"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> intent-filter> activity> <service android:name=".MyService"/> application>manifest>
需要注意的是上面的下面几个方法都需要先把Intent传参打开 ,这个程序中有启动service的程序,如果连service都没打开还怎么传
更多相关文章
- Android开发包下载(包括开发所需所有安装包的下载方法与地址)
- Android自定义相机开发相关知识点(全)
- Android实现自定义dialog的代码
- android开机自动运行程序
- Android获取系统时间方法的总结
- Android 应用程序如何获取system权限
- Intent传递对象的两种方法(Serializable,Parcelable)