[Android] startActivityForResult starts the Activity of singleTask, then onActivitResult() is called back immediately and resu

Problem phenomenon:

          When the demo application has just been installed and no account is logged in, I want to "send files/pictures to my friends" or "send to my computer" through the sharing function in the system, triggering the login interface, but after successful login, there is no jump Go to the interface of selecting demo friends to send, and cannot continue to send.

Code Analysis:

         In the demo, JumpActivity handles various external application sharing entrances. When sharing is found through debugging, it will judge whether you have logged in. If you have not logged in, it will jump to LoginActivity to log in. The following code:

private void doShare(booleancheckLogin) {  
          // system level sharing  
          Intent intent = getIntent();  
          ... ...  
          ... ...  
           
          // not logged in  
          if (checkLogin &&!demo.isLogin()){  
                   Intent i = newIntent(this, LoginActivity.class);  
                   i.putExtra("isActionSend",true);  
                   i.putExtras (extra);  
                   i.putExtras(i);  
                   startActivityForResult(i,SHARE_LOGIN_REQUEST);  
                   return;  
          }  
          ... ...  
}  

   After checking the code to know that the login is successful, JumpActivity.onActivityResult() will get a callback with the requestCode value of SHARE_LOGIN_REQUEST. To do this, set a breakpoint at the onActivityResult() callback and follow up again.

 

        

         Set a breakpoint, perform the sharing operation for debugging, and find that every time startActivityForResult() is executed, onActivityResult() is called back immediately, and the resultCode value is RESULT_CANCEL. At this point, the problem began to come to a head.

         Through investigation, it is found that LoginActivity has been changed before, and its launchMode is assigned to singleTask. The sharing function is disabled after this change. As long as the launchMode is restored to standard, onActivityResult() can be called back normally after the LoginActivity is successfully logged in, perform the sharing operation, and restore the function.

        

         So far, the problem has been solved, but the cause of the problem is still unclear:

Why start Activity with launchMode=singleTask through startActivityForResult() , onActivityResult() will be called back immediately and resultCode value is RESULT_CANCEL??   

Reason analysis:

After checking the document, I found that another similar method startActivityForResult(Intent, int, Bundle) in the document is described as follows:

Note that this method should only be used with Intent protocols thatare defined to return a result. In other protocols (such as ACTION_MAIN orACTION_VIEW), you may not get the result when you expect. For example,if the activity you are launching uses thesingleTask launch mode, it will not run in your task and thus you willimmediately receive a cancel result.

 

But this comment is still not very thorough. Continue to search and find that the following phenomenon is mentioned in the documentation (click here ).

In the figure below, there are the first two stacks, the Back Stack that is directly displayed on the screen to interact with the user, and the other Background Task that is hidden in the background. The launchMode of Activity Y at the top of the stack is singleTask .

If you call the Activity Y that has been started in the BackgroundTask in Activity 2, the Background Task will occupy the screen and all the stacks under the Task will retain the current stack position and order. Push into the Back Task to form a new structure, the order is from top to bottom It is Activity Y→Activity X→Activity 2→Activity 1.

在Activity Y界面按返回键,则ActivityY出栈,Activity X占据屏幕!注意,由Activity2调用的Activity Y,但返回键后,回退显示的是Activity X所以即使在Activity Y执行setResult(),Activity 2也是无法接收到的。换回文章开头的问题,即在JumpActivity处启动LoginActivity(已经被设置singleTask),则LoginActivitysetResult()结果有可能不会传给JumpActivity

继续按返回键,则才回到Activity 2。

 

 

 

问题结论:

由此,我们再回到先前的问题。在这种Tasks的入栈与出栈设计下,由于可能有Activity X的存在,所以在Activity 2启动Activity Y时,则直接回调了onActivityResult()并给出了RESULT_CANCEL也就可以理解了。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326129260&siteId=291194637