preface
It’s the end of the year and I’m going to put my Android knowledge in order.
Android Skill Book Series:
Android Basics
Android Skill Tree – Animation summary
Android Skill Tree – View summary
Android Skill Tree – Activity summary
Android Skill Tree – View event system summary
Android Skill Tree – Summary of Android storage paths and I/O operations
Android Skill Tree – Multi-process related summary
Android skill Tree – Drawable summary
Android Skill Tree – Fragment overview
Basic knowledge of data structures
Android Skill Tree – Array, linked list, hash table basic summary
Android Skill Tree — Basic Knowledge of The Tree
Basic knowledge of algorithms
Android Skill Tree – Sorting algorithm basics summary
This time is about Activity. It’s the same old thing, the brain map, and then I’ll go over it piece by piece.
Activity Brain map link
Activity Lifecycle
I bet if an interviewer asks you to review your Activity’s lifecycle, you’ll probably be cursing MMP. This is because the average newbie knows what is commonly used, although there may be some not commonly used, it is not clear, and the interviewer just wants to know a few commonly used.
For details of the life cycle, see my article:Super detailed life cycle map. – Can you answer all of them
Normal life cycle
Generally speaking, the life cycle we talk about is the following:
The two pairs are onstart-onstop and onresume-onpause.
Question 1:
OnStart — > onResume — > onResume — > onResume — > onStart — > onResume When we start a new Activity, or press the Home button to return to the desktop, onPause — > onStop is executed. When is onPause executed? When is onStop going to be executed? After the Activity starts, we see the screen, and then we can click the button on the screen.
- You can see the interface where we write the Activity.
- And then you can manipulate our interface.
So (onstart-onStop) depends on whether the interface is visible or not, and (onresume-onpause) depends on whether the interface is operable or not.
For example, if we have A button A on our Activity, and it starts A popup or A new transparent Activity, this button A cannot be pressed, but we can see that the button A does not execute onStop. But it will do onPause, because we can’t click the button anymore, but we can see the button.
Question 2:
If we jump from Activity A to Activity B, the two activities (onstart-onStop) and (onresume-onpause) are executed separately.
If you want to experiment, you just Log the corresponding life cycle. A(onPause) ->B(onCreate)->B(onStart) ->B(onResume) -> A(onStop)
Therefore, if you want to do something before jumping from one Activity to another, it is best to place it in onStop, because putting it in onPause will affect the speed at which the new Activity starts.
Abnormal life cycle
We can see from the brain map that during the abnormal life cycle, we perform two additional methods: OnSaveInstanceState (Bundle outState) and onRestoreInstanceState(Bundle savedInstanceState). We store some content in the onSaveInstanceState Bundle when the Activity is destroyed, and then we call onRestoreInstanceState to pass in the Bundle when the Activity is rebuilt, and then we can retrieve what we just saved.
Let’s start by looking at when an exception lifecycle occurs:
- Resource-related system configuration changes (most commonly screen rotation)
- Low priority activities are killed when memory is low
Let’s look at them separately:
Rotating screen
The simplest example is to write an Activity with an EditText:
public class SaveActivity extends AppCompatActivity {
TextView a;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("data"."Stored data");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.v("dyp", savedInstanceState.getString("data")); }}Copy the code
We rotate the phone screen, and in onSaveInstanceState, we save a string in the bundle, and then the Activity rebuilds and gets the string that we saved in the bundle in onRestoreInstanceState.
Print content: V/ DYP: stored dataCopy the code
Someone will ask. One of the things I noticed is that we have an EditText in our Activity, and I typed in 123456, and I didn’t do anything special in onSaveInstanceState or onRestoreInstanceState, but when the screen turns around, My EditText is still showing 123456. Let’s look at this phenomenon in detail.
We know that when we override onSaveInstanceState and onRestoreInstanceState, the default code looks like this:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
Copy the code
Since we don’t have to do extra processing, that illustrate key points in the super. OnSaveInstanceState (outState); And super onRestoreInstanceState (savedInstanceState); These two words. In simple terms: super onSaveInstanceState (outState); It saves the Activity’s associated views and then calls the onSaveInstanceState method for each View, such as the EditText method in its own class, which saves the input. Then in the super onRestoreInstanceState (savedInstanceState); Method will call the onRestoreInstanceState method of each View, so our EditText will call its own method and then assign the saved contents to it. So if we want to know what a particular View system can automatically restore for us, we can look at the View’s onSaveInstanceState and onRestoreInstanceState code (ListView will automatically restore the scroll position, etc.).
The priority of the Activity
Low-priority activities are killed when out of memory, and the data storage and recovery process is the same as described above.
How about the specific priority of the Activity:
- Foreground Activity – The Activity that is interacting with the user, highest priority.
- Activities that are visible but not actionable – such as the pop-up box we mentioned above.
- Background Activity – such as an Activity that executes onStop.
We can see that background activities are easy to kill, so some background work is better placed in services to ensure priority. Not easily killed by the system.
Life cycle switching process
Of course, as long as we know a few commonly used switching process can be pasted online other articles often used pictures:
How to start an Activity
In fact, there are too many articles about the way to start. I recommend these two articles for everyone to understand.
Basic knowledge: Thoroughly understand the four startup modes of Activity
Here is an advanced version of the startup mode article: Android interviewers install failed: Activity startup mode
Okay, I’m just being lazy. Don’t want to write a lengthy boot mode… Ha ha
Start the Activity
An Activity can be started explicitly or implicitly.
An explicit call to start the Activity
This is the most common way we do it. Simply write the name of the target Activity and start it with startActivity or startActivityForResult.
The usual code looks like this (such as starting TargetActivity from MainActivity) :
Intent intent = new Intent();
intent.setClass(MainActivity.this,TargetActivity.class);
startActivity(intent);
Copy the code
An implicit call starts the Activity
You may wonder, generally is the above kind of boot mode to start, then this implicit call is what use.
For example, we now need to click the button to enter and call the customer service number of our APP. We can’t ask the user to memorize the number every time and then manually open the phone and press it. We currently have a button on our Activity and set the button’s click event to:
Button btn = findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri data = Uri.parse("tel:10086"); Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(data); startActivity(intent); }});Copy the code
At this point, you click the button, we call the startActivity method, and it automatically jumps to the dial screen.
However, if we set a rule that matches multiple activities, a selection box will appear for you to select. Let’s say we open up a url in our app,
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri data=Uri.parse("http://www.baidu.com");
intent.setData(data);
startActivity(intent);
Copy the code
At this point, the following interface will pop up:
What about the specific matching rules? We can see that we have two lines of code above:
intent.setAction(Intent.ACTION_VIEW);
intent.setData(data);
Copy the code
So action and data must be matching rules, and there’s actually another category.
Ok, so let’s go back to how we can set the rules for an Activity, and then let other activities launch themselves implicitly, by setting the
tag in androidmanifest.xml. Do we remember that we set up an APP to start an Activity and use implicit calls as well?
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Copy the code
PS: Here we see categories.
Therefore, we only need to add the
tag in androidmanifest.xml, and then add the corresponding action,category,data and other filtering conditions. As long as the corresponding Activity meets the criteria, it will start the corresponding Activity.
The specific matching rules, above the brain map has also been written:
Pay attention to the point
Avoid an error when an Activity cannot be found during an implicit call
Use relevant methods to determine whether there is a matching Activity in advance.
Note the implicit invocation of categories
For example, we wrote this in androidmanifest.xml:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="dyp"/>
</intent-filter>
</activity>
Copy the code
We just set the filter for the Action, and then we want to start the MainActivity among other activities. Write the following code:
Intent intent = new Intent();
intent.setAction("dyp");
startActivity(intent);
Copy the code
You will notice that exceptions will be reported:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=dyp }
Copy the code
We can’t find it, because by default when we call startActivity or startActivityForResult we add a category to our Intent, Namely intent. Addcategory (” android. Intent. The category. The DEFAULT “); So if your activity
in androidmanifest.xml does not add this category, it will fail to match.
So we’re going to change it to something like this:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="dyp"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Copy the code
Notes on implicit calls to data
It’s similar to the category above, so I’m not going to do any specific examples. Just look at the brain map.
conclusion
The picture represents my heart… If there is anything wrong, please leave a comment. Ha ha.