解决 singleTask onActivityResult() 无效的问题
来源:互联网 发布:特效照片制作软件 编辑:程序博客网 时间:2024/04/30 23:13
(转载)http://mthli.github.io/singleTask-onActivityResult/
在 Android 4.X 系统上,如果你将一个 Activity A 的 launchMode 设置为 singleTask 或 singleInstance ,那么当你在 A 中调用startActivityForResult()
的时候,是不会像你想象的那样,在onActivityResult()
中获得你想要的返回结果的,就像官方文档说的那样:
For example, if the activity you are launching uses the singleTask launch mode, it will not run in your task and thus you will immediately receive a cancel result.
我们可以使用一个中介 Activity B 来解决这个问题,思路如下:
在 A 中通过
startActivity()
调用 B ,向 B 中传递你所需的 Intent I ;在 B 中通过
startActivityForResult()
调用 I ;在 B 中通过
onActivityResult()
获取 I 的返回结果,通过 Otto 向 A 发送结果,最后再 finish B 。
当然作为中介,我们需要对 B 进行一些配置。下面是一段简单的实例代码。
首先我们可以构造一个简单的 Agent 类,用于在 A 和 B 之间传递 Intent :
public class Agent implements Parcelable { private Intent intent; private int requestCode; // 用于判断是否需要在 AgentActivity 中使用 Intent.setComponentName() ; // 通常我们使用 Intent , // 都是类似 Intent intent = new Intent(Context, Class) 这样使用, // 所以对于传递给 B 的 Intent ,需要修改对应的 Context ; // 对于调用系统服务,比如相机,可设置为 false ; // 对于 App 内部的 Intent ,则设置为 true ; // 但通常来说如果只是调用 App 内部的 Intent , // 其实也没有必要使用中介,直接使用 Otto 就好了。 private boolean cls; public Agent(Intent intent, int requestCode, boolean cls) { this.intent = intent; this.requestCode = requestCode; this.cls = cls; } public Intent getIntent() { return intent; } public int getRequestCode() { return requestCode; } public boolean isCls() { return cls; } // Parcelable 接口的实现...}
接着我们创建 AgentActivity ,即上文提到的中介 Activity B :
public class AgentActivity extends Activity { public static final String EXTRA_AGENT = "extra_agent"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getIntent() == null) { finish(); return; } Agent agent = getIntent().getParcelableExtra(EXTRA_AGENT); if (agent == null || agent.getIntent() == null) { finish(); return; } // 判断是否需要替换从 A 传递进来的 Intent 的 Context 。 Intent intent = agent.getIntent(); if (agent.isCls()) { intent.setComponent( new ComponentName(this, intent.getComponent().getClassName()) ); } // 通过 B 调用 A 中构造的 Intent 。 startActivityForResult(intent, agent.getRequestCode()); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // BusProvider 是 Otto 单例的实现, AgentEvent 是自定义的 Otto 事件。 BusProvider.getInstance().post( new AgentEvent(requestCode, resultCode, data) ); finish(); }}
接下来是 AgentEvent 的实现:
public class AgentEvent { private int requestCode; private int resultCode; private Intent data; public AgentEvent(int requestCode, int resultCode, Intent data) { this.requestCode = requestCode; this.resultCode = resultCode; this.data = data; } public int getRequestCode() { return requestCode; } public int getResultCode() { return resultCode; } public Intent getData() { return data; }}
最后我们再在 AndroidManifest.xml 里面添加 AgentActivity 的声明:
<!-- 将 launchMode 设置为 standard ,同时将 theme 设置为不可见。--><activity android:name="YOUR_PACKAGE.AgentActivity" android:launchMode="standard" android:theme="@android:style/Theme.NoDisplay"></activity>
现在所有的准备工作都做完了,你只需要在 A 中这样使用就 OK :
public class A extend Activity { // 为了保证在整个生命周期内能接收到 Otto 的事件, // 选择在 onCreate() 和 onDestroy() 中注册与注销订阅。 @Override public void onCreate() { ... BusProvider.getInstance().register(this); } @Override public void onDestroy() { ... BusProvider.getInstance().unregister(this); } // 通过 AgentActivity 调用系统相机的示例。 private void startAgentToCamera() { Intent toCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Agent agent = new Agent(toCamera, YOUR_REQUEST_CODE, false); Intent toAgent = new Intent(getActivity(), AgentActivity.class); toAgent.putExtra(AgentActivity.EXTRA_AGENT, agent); startActivity(toAgent); } // 响应来自 AgentActivity 的事件。 @Subscribe public void onAgentEvent(AgentActivity.AgentEvent event) { int requestCode = event.getRequestCode(); int resultCode = event.getResultCode(); Intent data = event.getData(); // 处理你接收到的事件... }}
当然从上面的例子我们也可以看出,使用一个中介 Activity 的功能不止于此,你还可以用来处理一些只有 Activity 才能接收的 Intent Action 等。当然具体怎么使用,就请发挥你自己的想象力啦~
- 解决 singleTask onActivityResult() 无效的问题
- Fragment onActivityResult 无效的问题
- onActivityResult与singleTask或singleInstance的冲突问题
- onActivityResult与singleTask或singleInstance的
- onActivityResult不回调的问题的解决记录
- 关于Android的Cordova插件plugin OnActivityResult无效的问题
- singleTask、setResult、onActivityResult
- SingleTask与onActivityResult之间关系的简单讨论
- singleInstance或singleTask的设置导致onActivityResult回调失效
- 以singleTask启动的activity会直接调用OnActivityResult()方法
- 再也不需要onActivityResult了。使用响应式解决startActivityForResult和onActivityResult回调繁琐的问题
- 解决onActivityResult方法data为空的问题
- 解决Android Fragment 无法相应 onActivityResult 的问题.
- 解决onActivityResult()返回resultCode总是0的问题
- 关于startActivityForResult、onActivityResult和singleTask
- Fragment 嵌套 Fragment onActivityResult 无效的解决方法
- Android onActivityResult()的问题
- 解决ListView的 setEmptyView无效的问题
- Markdown用法简记
- 免费安装制作程序 Inno Setup
- 黑马程序员——反射
- iOS开源项目大全(二)(整理自网络)
- 关于集群--摘自群聊
- 解决 singleTask onActivityResult() 无效的问题
- IOS-自动布局和视图化语言1
- OC_多态
- C/C++常用算法【C语言顺序查找(随机数)】【1】
- 简单的网络协议介绍
- 将字符串转换成数字
- sap 教程编号
- 文章标题
- Eclipse中最有用的快捷键组合