我已经在我的Android应用程序中实现了一个ListView。我使用ArrayAdapter类的自定义子类绑定到这个ListView。在重写的ArrayAdapter.getView(…)方法中,我分配了一个OnClickListener。在OnClickListener的onClick方法中,我想启动一个新活动。我得到了一个异常:
Calling startActivity() from outside of an Activity context requires the
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
我怎样才能得到ListView(当前活动)正在工作的上下文?
另外:如果你在listview中以片段的形式显示链接,不要这样创建它
adapter = new ListAdapter(getActivity().getApplicationContext(),mStrings);
而不是打电话
adapter = new ListAdapter(getActivity(),mStrings);
适配器在这两种情况下都工作得很好,但链接只在最后一种情况下工作。
再详细阐述一下Alex Volovoy的回答
如果你在使用片段时遇到这个问题,getActivity()可以很好地获取上下文
其他情况:
如果你不想用-
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//not recommend
然后在你的outeclass -中创建一个这样的函数
public void gettingContext(Context context){
real_context = context;//where real_context is a global variable of type Context
}
现在,在你的主活动中,当你创建一个新的outeclass时,在你定义了以活动的上下文作为参数的outeclass之后,立即调用上面的方法。
在你的主要活动中也做一个函数-
public void startNewActivity(final String activity_to_start) {
if(activity_to_start.equals("ACTIVITY_KEY"));
//ACTIVITY_KEY-is a custom key,just to
//differentiate different activities
Intent i = new Intent(MainActivity.this, ActivityToStartName.class);
activity_context.startActivity(i);
}//you can make a if-else ladder or use switch-case
现在回到你的outeclass,并开始一个新的活动,像这样做-
@Override
public void onClick(View v) {
........
case R.id.any_button:
MainActivity mainAct = (MainActivity) real_context;
mainAct.startNewActivity("ACTIVITY_KEY");
break;
}
........
}
通过这种方式,您将能够从不同的outside eclass启动不同的活动,而不会弄乱标志。
注意-尽量不要通过构造函数缓存上下文对象的片段(与适配器,它的好)。一个片段应该有一个空的构造函数,否则应用程序在某些情况下崩溃。
记得打电话
OutsideClass.gettingContext(Context context);
在onResume()函数中也一样。
如果你因为使用创建选择器而出错,如下所示:
Intent sharingIntent = new Intent(Intent.ACTION_VIEW);
sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sharingIntent.setData(Uri.parse("http://google.com"));
startActivity(Intent.createChooser(sharingIntent, "Open With"));
设置标志以创建选择器,如下所示:
Intent sharingIntent = new Intent(Intent.ACTION_VIEW);
sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sharingIntent.setData(Uri.parse("http://google.com"));
Intent chooserIntent = Intent.createChooser(sharingIntent, "Open With");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(chooserIntent);
我的情况有点不同,我正在使用Espresso测试我的应用程序,我必须从仪器环境中启动我的活动与ActivityTestRule(这不是一个来自活动)。
fun intent(context: Context) =
Intent(context, HomeActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
我不得不改变标志,并添加一个或位(在Java中|)与意图。FLAG_ACTIVITY_NEW_TASK
结果是:
fun intent(context: Context) =
Intent(context, HomeActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
在Android 28(Android P)启动活动
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
&& (targetSdkVersion < Build.VERSION_CODES.N
|| targetSdkVersion >= Build.VERSION_CODES.P)
&& (options == null
|| ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
所以最好的方法是添加FLAG_ACTIVITY_NEW_TASK
Intent intent = new Intent(context, XXXActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);