Android低版本Adapter调用startActivity触发AndroidRuntimeException崩溃
解决低版本Android中Adapter调用startActivity崩溃的问题
我之前也碰到过一模一样的情况:高版本设备分享功能正常,低版本(比如Android 6.0及以下)点击分享按钮就直接崩,报错就是你提到的android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity。
问题根源
你已经给分享Intent加了Intent.FLAG_ACTIVITY_NEW_TASK,但低版本系统里有个坑:Intent.createChooser()生成的新Intent并不会继承原Intent的flags,而且如果Adapter里的context是Application Context而非Activity Context,低版本系统对这种非Activity上下文启动交互类Activity的校验会更严格,直接触发崩溃。
修复方案
这里有两种可靠的解决办法,按优先级推荐:
方法一:用Activity Context初始化Adapter
这是最稳妥的方案。在创建Adapter的时候,传入当前Activity的实例(比如YourActivity.this),而不是getApplicationContext()。这样用Activity Context启动Activity,不需要额外加flags也能正常工作:
// 初始化Adapter时传入Activity实例 YourAdapter adapter = new YourAdapter(YourActivity.this, 你的其他参数);
然后修改Adapter里的点击事件代码:
share.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String shareBody = "\t\t DIL KI BAAT \n\n" + sayari[position].toString().trim() + "\n\n\n" + "https://play.google.com/store/apps/details?id=" + appPackageName; Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody); // 直接用Activity Context启动选择器,无需额外flags context.startActivity(Intent.createChooser(sharingIntent, context.getResources().getString(R.string.app_name))); } });
方法二:给createChooser返回的Intent添加FLAG_ACTIVITY_NEW_TASK
如果因为某些限制必须用Application Context,那要把flags添加到createChooser返回的最终Intent上,而不是原分享Intent:
share.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String shareBody = "\t\t DIL KI BAAT \n\n" + sayari[position].toString().trim() + "\n\n\n" + "https://play.google.com/store/apps/details?id=" + appPackageName; Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody); // 创建选择器Intent并给它添加FLAG_ACTIVITY_NEW_TASK Intent chooserIntent = Intent.createChooser(sharingIntent, context.getResources().getString(R.string.app_name)); chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(chooserIntent); } });
为什么这样有效?
- 方法一用Activity Context启动Activity是Android的标准做法,系统会自动处理Activity栈的逻辑,不会触发权限类异常。
- 方法二中,
createChooser()会生成一个全新的Intent来展示分享选择器,低版本系统只会检查这个最终启动的Intent的flags,所以把FLAG_ACTIVITY_NEW_TASK加在它身上才能生效。
建议优先试方法一,兼容性最好。
内容的提问来源于stack exchange,提问作者Dharmendra Kanpara
相关产品推荐
相关产品推荐

