从另一个活动调用时为空侦听器
Posted
技术标签:
【中文标题】从另一个活动调用时为空侦听器【英文标题】:Null listener when called from another activity 【发布时间】:2018-07-20 23:41:29 【问题描述】:在 android 中,我试图在第二个活动中完成任务时设置回调侦听器。流程如下:
MainActivity 开始 -> 调用第二个 Activity -> 当第二个 Activity 完成时调用监听器 -> 返回到 Main Activity
我已经用下面的代码做到了:
//// First activity
Main Activity
// Reference to second activity
private IntroActivity mIntroActivity;
@Override
protected void onCreate(Bundle savedInstanceState)
/// Listener reference
mIntroActivity = new IntroActivity();
Intent i = new Intent(MainActivity.this, IntroActivity.class);
startActivity(i);
/// Call back for second activity
mIntroActivity.setIntroListener(new IntroActivity.IntroListener()
@Override
public void finished()
/// When finished do something!
);
/// Second Activity
public class IntroActivity extends AppIntro
/// Listener setup
public interface IntroListener
void finished();
public void setIntroListener(IntroListener listener)
this.mIntroListen = listener;
public IntroActivity()
this.mIntroListen = null;
private IntroListener mIntroListen;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
@Override
public void onDonePressed(Fragment currentFragment)
super.onDonePressed(currentFragment);
/// Call listenr from MainActivity
mIntroListen.finished();
为第二个活动添加一个接口监听器。当这个活动完成时,调用finished() 并返回到MainActivity。
我遇到的问题是 mIntroListen.finished();在第二个活动中为空。
这里的任何想法都会很棒。我在另一个项目中使用相同的接口/侦听器(这是另一个类而不是活动),所以我不确定出了什么问题。
提前致谢!
【问题讨论】:
不完全确定,但这可能是因为当你移动到第二个活动时,android 正在清理资源,而不是这样做,要么使用像 greenrobot/EventBus 这样的事件总线,要么使用本地广播管理器,这样你的代码就解耦了,空指针异常的变化也少了 我现在去看看greenrobot。 【参考方案1】:我遇到的问题是 mIntroListen.finished();在第二个活动中为空。
您将始终获得null
,因为mIntroActivity
实例和您实际运行的IntroActivity
实例不同。
mIntroActivity = new IntroActivity();
以这种方式创建活动不是一个好主意。要启动Activity
,您应该始终使用startActivity()
。
如果您想使用来自IntroActivity
的一些数据返回MainActivity
,或者只是在完成呼叫侦听器时返回,您应该在MainActivity
中使用startActivityForResult(intent)
。此方法将为您提供设置您在IntroActivity
中找到的结果的选项,您可以通过onActivityResult()
方法在MainActivity
中使用这些结果。
对于您的情况,请使用startActivityForResult(intent)
启动您的IntroActivity
,并在完成呼叫侦听器时完成IntroActivity
然后onActivityResult()
方法将在MainActivity
中调用。在onActivityResult()
做你想做的事
查看这个官方链接Getting a Result from an Activity也可以查看这个answer
【讨论】:
【参考方案2】:您实际上并没有通过调用 new 来初始化第二个活动,这甚至不是一个好主意。
我相信有更好的方法来使用处理程序来完成你的工作,如下所示:
在MainActivity
中声明一个处理程序并像下面这样简单地实例化它:
private Handler = new Handler()
public void handleMessage(Message message)
// Do your jobs
使用Messenger
将带有您意图的处理程序发送到第二个活动:
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("key_handler", new Messenger(handler));
startActivity(intent);`
在SecondActivity.class
中获取意图,并从中提取信使,当您的第二个活动完成其工作时,只需调用messenger.send(message)
将消息发送回主活动。
Intent intent = getIntent();
Messenger messenger = intent.getExtras("key_handler");
// Do jobs .....
// When done, call send method on messenger, maybe you want sth to sent back to main activity, just use bundle.
Message message = Message.obtainMessage();
Bundle bundle = new Bundle();
// Put sth in the bundle, then call setData()
message.setData(bundle);
messenger.send(message)`
返回handleMessage(Message message)
获取您的信息。
请注意,上面的内容只是为了更简单的答案而被忽略,您必须自己进行一些搜索才能正确使用。
【讨论】:
【参考方案3】:如果您仔细研究以下代码部分,您会发现当您创建 Intent
时,您传递的是 IntroActivity.class
。这意味着您只是传递了一个Class
reference,而不是该类的实例化对象。因此,当活动启动时,它不会引用您实例化的mIntroActivity
。所以,显然introListener
也将是null
。这是预期的行为。
/// Listener reference
mIntroActivity = new IntroActivity();
Intent i = new Intent(MainActivity.this, IntroActivity.class);
startActivity(i);
/// Call back for second activity
mIntroActivity.setIntroListener(new IntroActivity.IntroListener()
@Override
public void finished()
/// When finished do something!
);
要从已启动的活动中获取结果,您必须使用startActivityForResult(Intent intent)
。请查看documentation 了解更多信息。
修改后的代码如下所示。
主要活动
private static final int INTRO_ACTIVITY_REQUEST_CODE = 771;
@Override
protected void onCreate(Bundle savedInstanceState)
Intent i = new Intent(MainActivity.this, IntroActivity.class);
startActivityForResult(i, INTRO_ACTIVITY_REQUEST_CODE);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == INTRO_ACTIVITY_REQUEST_CODE)
if (resultCode == RESULT_OK)
String resultValue = data.getStringExtra("KEY");
介绍活动
@Override
public void onDonePressed(Fragment currentFragment)
super.onDonePressed(currentFragment);
Intent resultIntent = new Intent();
resultIntent.putExtra("KEY", "VALUE");
setResult(RESULT_OK, resultIntent); // RESULT_OK means success
finish();
【讨论】:
【参考方案4】:查看startActivityForResult(Intent, Key)的文档
您应该使用它从另一个活动中获取结果。
使用new()
实例化活动是错误的。
【讨论】:
以上是关于从另一个活动调用时为空侦听器的主要内容,如果未能解决你的问题,请参考以下文章