详解App相互唤醒的几种方式
下文皆使用client表示操作的app,server表示需要被唤起的远端app,server的包名为“com.jxx.server”
1. componentname
使用componentname唤起server步骤很简单,需要注意的是server的activity需要在manifest配置种设置exported为true
server的配置如下:
<activity android:name="com.jxx.server.serveractivity" android:exported="true"/>
client调用如下:
intent intent1 = new intent(); componentname componentname = new componentname("com.jxx.server", "com.jxx.server.serveractivity"); intent1.setcomponent(componentname); intent1.setflags(intent.flag_activity_new_task); startactivity(intent1);
intent中添加componentname还有另外一种写法
intent intent2 = new intent(); intent2.setclassname("jxx.com.server", "jxx.com.server.mainactivity"); intent2.setflags(intent.flag_activity_new_task); startactivity(intent1);
只不过setclassname内部帮我们new componentname的实例
public @nonnull intent setclassname(@nonnull string packagename, @nonnull string classname) { mcomponent = new componentname(packagename, classname); return this; }
既然是用intent来唤起activity,那就能使用intent的特性,例如使用bundle传递数据
intent intent1 = new intent(); componentname componentname = new componentname("com.jxx.server", "com.jxx.server.serveractivity"); intent1.setcomponent(componentname); bundle bundle1 = new bundle(); bundle1.putstring("remote_invoke", "from_client"); intent1.putextras(bundle1); intent1.setflags(intent.flag_activity_new_task); startactivity(intent1);
在server端提取数据也很简单
bundle bundle = getintent().getextras();
2. 隐式跳转,uri
android中唤起拨号页面是这样的
intent intent = new intent(intent.action_call,uri.parse("tel:" + phonenumber)); startactivity(intent);
其实就是用uri的形式唤起server,并传递数据,我们来自己实现一下。 这种方式下,server端的配置如下,必须添加要有action、data以及category:
<activity android:name=".secondactivity"> <intent-filter> <action android:name="com.jxx.server.serveractivity" /> <data android:host="com.jxx.server" android:scheme="serveractivity" /> <category android:name="android.intent.category.default" /> </intent-filter> </activity>
client调用:
intent intent2 = new intent("com.jxx.server.serveractivity"); uri uri = uri.parse("serveractivity://com.jxx.server?remote_invoke=from_client"); intent2.setdata(uri); startactivity(intent2);
我们看到uri中?后面还加了"remote_invoke=from_client",这其实是用来给server传递数据用的,我们可以在server中解析出来
uri uri = getintent().getdata(); string from = uri.getqueryparameter("remote_invoke"); //from = "from_client"
这里还有一个需要注意的点是,如果client在调用时没有指定action,同时server中又有多个activity注册了相同的scheme和host,那么在页面跳转时,系统会弹框让我们选择跳转到哪个页面,如下图所示:
3. 通过packagemanager唤起
只需要知道server的包名即可
packagemanager packagemanager = getpackagemanager(); intent intent3 = packagemanager.getlaunchintentforpackage("com.jxx.server"); if (intent3 != null) { startactivity(intent3); }
4. 静态广播接收者
只需要server端注册一个静态广播接收者,在广播接收者中跳转activity即可,客户端只需要发送一个广播。
server定义广播接收者:
public class serverbroadcastreceiver extends broadcastreceiver { @override public void onreceive(context context, intent intent) { intent intent1 = new intent(context, mainactivity.class); //注意,这里必须要添加这个flag, //原因在于这里的context并不是一个activity类型的context,无法直接开启activity intent1.setflags(intent.flag_activity_new_task); context.startactivity(intent1); } }
并在manifest中注册为静态广播接收者,并定义action
<receiver android:name=".serverbroadcastreceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="server.serverbroadcastreceiver" /> </intent-filter> </receiver>
client中发送广播即可
intent intent4 = new intent("server.serverbroadcastreceiver"); //这里加上componentname用于解决8.0以上不能唤起的问题 componentname componentname = new componentname("com.jxx.server", "com.jxx.server.serverbroadcastreceiver"); intent4.setcomponent(componentname); sendbroadcast(intent4);
5. service
在android service详解(二) 中我们介绍了如何通过service实现ipc通信,这当然也能用来唤起app,这里就不再过多介绍了,有兴趣的同学可以点击查看。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。