跨进程调用Activity

【跨进程调用activity】

跨进程调用Activity的目的比较简单,就是Application A中,有个Activity,想要给其它Application B调用,这时候就要分两步进行:

(1) 在Application A的Manifest中设置Activity的属性

[java]  view plain copy print ?
  1. <activity  
  2. android:name=".SubActivity"  //该activity的class name  
  3. android:exported="true">   
  4. <intent-filter>    
  5. <action android:name="net.blogjava.mobile.MYACTION"/>    
  6. <data android:scheme="info"/>  
  7. <category android:name="android.intent.category.DEFAULT" />            
  8. </intent-filter>  
  9. </activity>  

上述代码中:

a.  android:exported="true" :设置为"True"则表示将该Activity暴露给外部;但在本demo中发现,这个属性可以不用设置,demo也是生效。这是因为:设置了intentFilter之后,exported就默认被设置为true了,除非再强制设为false。

b.  <action android:name="net.blogjava.mobile.MYACTION"/> :这里是设置Intent对应的名字,在调用的时候,需要该名字。当然这里也可以为空。(若为空串,调用的时候需要指定调用activity的包名和类名,后文详述)

c.  <data android:scheme="info"/> :data元素用于把数据规范添加到一个Intent过滤器中,如果这里定义了info,那在intent中就需要添加uri为“info://”的字样;如果name为空,这里也就不需要设置;

关于data的详细介绍,参考 http://blog.csdn.net/fireofstar/article/details/7561589

d.  <category android:name="android.intent.category.DEFAULT" /> : 意思是说,每一个通过 startActivity() 方法发出的隐式 Intent 都至少有一个 category,就是 "android.intent.category.DEFAULT",所以只要是想接收一个隐式 Intent 的 Activity 都应该包括 "android.intent.category.DEFAULT" category,不然将导致 Intent 匹配失败。
从上面的论述还可以获得以下信息:  1、一个 Intent 可以有多个 category,但至少会有一个,也是默认的一个 category。 2、只有 Intent 的所有 category 都匹配上,Activity 才会接收这个 Intent。

这四个部分是注册时候的主要动作,但a可以无视,正如前面所说; d是不可缺少的,若少了,则无法调用成功,会提示找不到Activity的错误。(关于隐式Intent的内容,有专门的文章,之前看过但现在有点忘了,下次再整理下)

(2) 在Application B 中启动intent,调用该Activity

调用的code比较简单,如下:

[java]  view plain copy print ?
  1. Intent i =  new Intent("net.blogjava.mobile.MYACTION", Uri.parse("info://111"));  
  2. this.startActivity(i);  
  3. Log.v("HelloActivity" , "Start the new activity");  

new Intent中,第一个参数就是(1)中配置的action name,两者要一致;第二个参数就是data类型,前面的"info://"不可少,而info后面的内容可以随意,当然你也可以添加有意义的内容。


另外一种方式是:

[java]  view plain copy print ?
  1. Intent intent = new Intent();  
  2. ComponentName cn=new ComponentName("com.example.phonelistenertest",  
  3.                 "com.example.phonelistenertest.SubActivity");    
  4. intent.setComponent(cn);  
  5. startActivity(intent);    

这里,只需要指定你需要调用的Activity是在哪个包中,以及类名是什么,即格式为:(包名,包名+类名)

而Application A中的Manifest只需要配置如下:

[java]  view plain copy print ?
  1. <activity  
  2.             android:name=".SubActivity"  
  3.             android:exported="true"  
  4.            >  

即,只需要指定该Activity的名字,并将它暴露给外部就行,可以不用设置Intent-filter。同样,如果你没有设置exported属性,会提示错误权限不允许访问SubActivity。也可以用个设置一个空的intent-filter来打开该属性,这也是网上为什么有的例子添加了intent-filter,但只有一个空串action的缘故。

这里也应该是跟Intent的显式,隐式调用方式有关。


【SingleTask】

现有2个项目,taskA、taskB。taskA负责调用taskB中指定的界面。
taskB中有3个界面,a、b、c,每个界面显示它所在的task id。

SingleTask
其中b界面被声明为SingleTask。
先运行taskB,显示a界面,由a界面调用b界面,这时b界面的taskid与a界面的taskid是一致的,说明b界面与a界面在同一个task中;由b界面调用c界面时,c界面的taskid与a和b界面的taskid一致,说明这三个界面是在同一个task中。当前显示的是c界面,此时按Home键回到桌面,运行taskA的界面调用taskB的b界面,这时b界面显示出来,它的taskid没有变,还是之前的taskid,只不过之前显示的是c界面,这时c界面已经不知所踪,这时再按back键,则回到了a界面,然后是taskA的界面。

这说明,SingleTask所标注的Activity在被自身的app调用时,是不新建task的,同时,如果系统中存在了这个SingleTask界面的实例时,会将其所在的task切换到前台,并把SingleTask界面之后开启的其他界面全部关闭(有待考证是否关闭)。

另外有一种情况,例如:a界面被调用,这时按Home键返回到桌面,启动taskA,并调用b界面,这时b界面的taskid与a界面的一致,说明b界面与a界面同属于一个task。如果直接运行taskA调用b界面,b的taskid与taskA的界面的taskid不同,说明在新task中实例化了b界面,由b界面调用c界面,c界面的taskid与b界面一致,说明b与c同属于一个task。


SingleInstance

将b界面声明为SingleInstance。

先运行taskB,显示a界面,由a界面调用b界面,这时b界面的taskid与a界面的taskid不同,说明b界面是在新task中生成的实例;由b界面调用c界面,c界面的taskid与a界面的taskid相同,说明a、c界面同属于一个task。

由此可以看出SingleTask与SingleInstance是有本质区别的,而不是像网上说的那样,都是task的root activity,这是有错误的。

 文章来源: http://blog.csdn.net/wang_zun_ren/article/details/6823257

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值