在重新获得焦点之前无法完成暂停的活动

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状态的人?我还没有找到关于此的文档,也许有人知道相关的文档/代码?

编辑看到我的答案

Jon*_*win 8

嗯,这个问题比它看起来更棘手,透明的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