Eri*_* S. 16 multithreading android
我想完成()一个透明活动下面的暂停活动.
我有一项活动,称为活动A.当活动A处于活动状态时,可能会发生两件事;
我们可以启动(透明)活动B.
我们可以接收异步回调来完成活动A.
这两个动作彼此非常接近.代码看起来像这样
public class ActivityA extends Activity
{
public class DataHandler implements ContentLoader.OnDataListener
{
@Override
public void onData(Cursor data)
{
_binder.bind(data);
}
}
//If this callback is executed while Activity A is paused, it will not go into onStop until it the activity above it is finished
private class LoaderCallbacks extends ContentLoader.LoaderCallbacks
{
public LoaderCallbacks(ContentLoader loader)
{
super(loader);
}
@Override
public void onLoadFinished(
Loader<Cursor> loader,
Cursor cursor)
{
if (cursor == null || cursor.getCount() <= 0)
{
Log.d("Eric", "* ON FINISH *");
finish();
finishagain();
return;
}
super.onLoadFinished(loader, cursor);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在此活动显示的listfragment内部,有一个启动Activity B的机制
public class FragmentA extends ListFragment
{
//Some fragment functions here...
@Override
public void onListItemClick(
ListView list,
View view,
int position,
long id)
{
Intent intent = new Intent();
intent.setAction(Intent.LAUNCH_ACTIVITY_B);
getActivity().sendBroadcast(intent)
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是当完成活动A的回调被称为AFTER活动B被启动,然后活动A没有立即完成.它一直处于暂停状态,直到活动B结束,然后两者都完成.这是一个竞争条件,我已经通过尝试再次完成来确认这一点,而在暂停状态下,使用一个简单的等待线程.正如预期的那样,所有结束调用都在主线程上执行.
private void finishagain()
{
Handler handler = new Handler();
int LOCK_HOME_DELAY = 5000;
handler.postDelayed(new Runnable()
{
public void run()
{
if (notfinished){
Log.d("Eric", "*************** FINISH AGAIN ****************");
finish(); //Does nothing while the activity is paused
}
else{
Log.d("Eric", "* Times up do nothing *");
}
}
}, LOCK_HOME_DELAY);
}
Run Code Online (Sandbox Code Playgroud)
这是我的日志(一些软件包名称可能会被编辑)
10-10 18:23:05.168 74-98/system_process I/ActivityManager: Displayed somepackage/com.eric.activity.A: +894ms
10-10 18:23:07.135 74-98/system_process I/ActivityManager: Displayed somepackage/com.eric.activity.B: +343ms
10-10 18:23:07.102 547-547/somepackage D/Eric: * Times up do nothign *
10-10 18:23:07.231 547-547/somepackage D/Eric: * ON FINISH *
10-10 18:23:08.220 547-547/com.eric.Status D/Eric: * Times up do nothign *
10-10 18:23:08.305 547-547/com.eric.Status D/Eric: * Times up do nothign *
10-10 18:23:12.305 547-547/com.eric.Status D/Eric: *************** FINISH AGAIN ****************
10-10 18:23:12.305 74-668/system_process W/ActivityManager: Finishing task with all activities already finished
10-10 18:23:12.305 74-668/system_process W/ActivityManager: Duplicate finish request for ActivityRecord{3627639c u0 somepackage/com.eric.activity.A t2292 f}
Run Code Online (Sandbox Code Playgroud)
(注意时间戳 - 我称之为:07秒完成,并且它没有完成.finoneAgain()再次调用:12秒,它似乎在这里关闭,但我已经看到它也完成了.还要注意"复制完成请求" - 对我来说,它看起来像是排队等待的东西).
如何在透明活动B下面暂停活动A以完成活动A?
说实话,我很惊讶这是一个问题; 我认为在靠背上的活动应该是容易杀人的,但也许不是那些处于onPause状态的人?我还没有找到关于此的文档,也许有人知道相关的文档/代码?
编辑看到我的答案
嗯,这个问题比它看起来更棘手,透明的Activity会导致问题.你解释得很好,但人们通常不会回答这个问题,他们会把他们熟悉的东西说出来.
"如果一项活动失去焦点但仍然可见(即,一项新的非全尺寸或透明活动专注于您的活动之上),它会暂停.暂停的活动完全存在(它保持所有状态和成员信息并保持附加到窗口管理器),但可以在极低内存情况下被系统杀死." 看到android doc.
你说:
//如果在活动A暂停时执行此回调,它将不会进入onStop,直到它上面的活动结束
当活动A可见时,您无法进入停止状态.Android销毁活动,查杀过程
这可能会有所帮助:
View topLevelLayout = findViewById(R.id.top_layout);
topLevelLayout.setVisibility(View.INVISIBLE);
Run Code Online (Sandbox Code Playgroud)
在我的回答中,默认情况是异步的(它是广播).注册的每个活动(您想以后杀,ActivityA
)对本地广播它被创建的时候.当它进入后台(暂停状态)时,(即,一个新活动到达堆栈的顶部),它的onPause()
{ onStop()
}将被调用,但它仍然可以接收广播.您只需要确保调用unregisterReceiver()onDestroy()
而不是onPause()
{ onStop()
}.
这里有一些示例代码可以提供您的想法:
/** your "kill" method (ActivityA) **/
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_KILL");//some string
// sendBroadcast(broadcastIntent);//global broadcast
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
/** The receiver (ActivityA) **/
BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.package.ACTION_KILL");//some string
LocalBroadcastManager.getInstance(this).registerReceiver(myBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("onReceive","KILL in progress");
//At this point you should do your stuff ;O)
finish();//kill it
//System.exit(0)// to clear static variables
//android.os.Process.killProcess(android.os.Process.myPid());//"cave man" kill }
}, intentFilter);
}
protected void onDestroy(
{
LocalBroadcastManager.getInstance(this).unregisterReceiver(myBroadcastReceiver );
super.onDestroy();
}
Run Code Online (Sandbox Code Playgroud)
https://developer.android.com/training/basics/activity-lifecycle/index.html https://developer.android.com/reference/android/app/Activity.html https://developer.android.com/参考/机器人/内容/ BroadcastReceiver.html
归档时间: |
|
查看次数: |
1932 次 |
最近记录: |