Based on some

Activity Lifecycle

onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDetroy()

Brief description of picture

  • Start onCreate -> onStart -> onResume
  • Overwrite/return to current interface onPause -> / -> onResume
  • In the background onPause -> onStop
  • Go back to onRestart -> onStart -> onResume
  • Exit onPause -> onStop -> onDestory

There are two other important ones

  • OnSaveInstanceState: (1) This method is called when an Activity is overwritten or left in the background and is killed due to insufficient system resources; (2) This method is called when the user changes the direction of the screen (the system destroys the current Activity and then recreates a new one, so we can save some temporary data while calling this method); (3) When the current Activity jumps to another Activity or presses the Home button to return to the Home screen and retires to the background, the system calls this method to save the state of each View component in the current window. OnSaveInstanceState This method is called before onStop, but is not timed with onPause. However, onSaveInstanceState() is used to hold temporary data, while onPause() is used to hold persistent data.

  • OnRestoreInstanceState: onRestoreInstanceState is called in the order after onStart. It is mainly used to restore some data saved in the onSaveInstanceState method

Difference between onStart() and onResume()/onPause() and onStop()

OnStart () and onStop() are called from the point of view of whether the Activity is visible. OnResume () and onPause() are called from the point of view of whether the Activity is in the foreground.

Activity A jumps to Activity B

Method that Activity A starts another Activity B will call back: Activity A’s onPause() –>Activity B’s onCreate()–>onStart()–>onResume()–>Activity A’s onStop();

If Activity B is completely transparent, Activity A’s onStop() is not called at the end; If it is A dialog Activity, onStop() of Activity A is not called at the end;

Activity Startup process

After calling startActivity(), the methods are transferred to startActivity() of the ActivityManagerService and returned to ApplicationThread, the ActivityThread’s inner class, via an IPC. And calls its scheduleLaunchActivity() to send a message to Handler H to start the Activity. Handler H handles the message by calling handleLaunchActivity()->performLaunchActivity() to complete the creation and launch of the Activity object.

Refer to: Activity Start process

Fragment Life cycle

The methods involved in the entire Fragment lifecycle from creation to destruction are as follows: onAttach()->onCreate()-> onCreateView()->onActivityCreated()->onStart()->onResume()->onPause()->onStop()->onDestroyView()->onDestroy()->onDetach( ), there are a number of activities with the same name that have similar effects. The different methods are:

OnAttach () : called when an Fragment is associated with an Activity

OnCreateView () : called when the Fragment is creating a view

OnActivityCreated () : Called after the Activity associated with the Fragment has completed onCreate()

OnDestroyView () : Called when the layout in the Fragment has been removed

OnDetach () : called when a Fragment is disassociating from an Activity

Activities communicate with fragments

  1. For calls between activities and fragments

(1) The Activity calls the Fragment directly, the Activity usually holds the Fragment instance, (2) The Fragment calls the Activity to callback the Fragment by setting the listener to the Fragment. Or get the activity instance directly from the fragment

  1. Activity if better to pass parameters to the Fragment

If the parameters are passed directly through the call to the normal method, the data cannot be recovered after the fragment collection. Google has given us a method that we can use to pass the arguments to the fragment, which we can use for getArguments (bundle) in the fragment. Ensure that data can be retrieved after fragment destruction

Service startup and life cycle

Service Startup mode

  • Cannot communicate with Service. Started with startService() and not closed with the caller
  • Can communicate with Service. Start using bindService(). Close after the caller closes

By default, both Servcie are in the same process as the caller. If you want to set them differently, you need to configure the Android :process = Remote property in androidmanifest.xml

Life cycle:

  • The life cycle of a service started by startService() is startService() –> onCreate()–> onStartConmon()–> onDestroy().

Several issues need to be noted:

The onCreate() method is only called once when we call startService() several times. OnStartConmon () will be called multiple times when we call stopService(), onDestroy() will be called to destroy the service. 2. When we start with startService, we pass the intent value. When we get the value from onStartConmon(), we must first check whether the intent is null.Copy the code
  • BindService –>onCreate()–>onBind()–>unBind()–>onDestroy()

The advantage of bindService is that it makes it easier for an activity to start a service. For example, there are several methods in the service, a,b, and if you want to call them in the activity, We need to get a ServiceConnection object from the activity. We need to get a class object from the inner class of the service. Then we can use this class object to call methods in the class

Service Communication mode

  1. Create an inner class that inherits the Binder, and override the Service’s onBind method to return a Binder subclass. Override the ServiceConnection, onServiceConnected, and call a logical method to bind the Service.

  2. Call the Service method through the interface Iservice

IntentService contrast Service

IntentService is a subclass of Service, is an asynchronous, will automatically stop of the services, well solve the traditional Service processes the time-consuming operation forget to stop and destroy the Service

Advantages:

  • When all requests are processed, IntentService stops automatically without calling stopSelf()
  • IntentService does not block the UI thread, whereas normal service causes an ANR exception
  • If Intentservice does not complete the previous task, it will not open a new thread, it will wait for the previous task to complete, then execute the new task, and then call stopSelf() again.
  • Provides a default implementation of onBind() for Service, returning null;

The priority of the service is increased

  1. In the AndroidManifest. XML file, you can use the Android :priority = “1000” attribute to set the highest priority for an Intent-filter. 1000 is the highest value.
  2. The onStartCommand method returns START_STICKY manually.
  3. Monitor system broadcasts to determine Service status.
  4. Application has the Persistent attribute.
  5. The startForeground() method in onStartCommand is invoked to elevate the Service to the foreground process level, and the stopForeground () method in onDestroy is invoked.
  6. Send a broadcast in the onDestroy method to restart the service.

In the service +broadcast mode, the service sends a custom broadcast when it goes through ondeStory, and restarts the service when it receives the broadcast.

Extension: Process to keep alive (cancer)

Black keepalive: different APP processes wake up each other with broadcast (including using the broadcast provided by the system to wake up) White keepalive: start foreground Service Gray keepalive: start foreground Service by using the system vulnerabilityCopy the code

Black keepalive The so-called black keepalive is the use of different app processes to use the broadcast to wake up each other. For example, there are three common scenarios: Scenario 1: When starting up, switching over the network, taking photos, and shooting videos, the system generates broadcasts to wake up the app. Scenario 2: When accessing the third-party SDK, the corresponding APP process will also be woken up. For example, the wechat SDK will wake up wechat, and the Alipay SDK will wake up Alipay. Diverge from this, will directly trigger the following scene 3 scene 3: if your mobile phone installed Alipay, Taobao, Tmall, UC and other Ali app, so you open any Ali app, it is possible to the other Ali app by the way to wake up. (Just take Ali as an example, in fact, BAT series are almost the same)

White keepalive is as simple as calling the system API to start a foreground Service process, which generates a Notification in the system Notification bar to let the user know that an app is running, even if the current app is in the background. The following side of LBE and QQ Music like this:

Gray survival, this means of survival is the most widely used. It takes advantage of a vulnerability in the system to start a foreground Service process. Unlike normal startup methods, it does not appear as a Notification in the system Notification bar. It looks like a background Service process is running. The advantage of this is that the user is not aware that you are running a foreground process (because there is no Notification), but your process has a higher priority than a normal background process. Then how to use the system vulnerability, the general implementation of the train of thought and code is as follows: Idea 1: API < 18, start the foreground Service directly into the new Notification(); Idea 2: API >= 18, at the same time start two id of the same foreground Service, and then start the Service to stop processing familiar with Android system, system for the sake of experience and performance, the system will not really kill this process when the app back to the background, I’m going to cache it. The more applications open, the more background caching processes. In the case of insufficient system memory, the system begins to determine which processes to kill according to its own set of process reclamation mechanism, in order to free up memory to supply the needed app. This mechanism is called Low Memory Killer, which is based on the OOM Killer (out-of-memory Killer) mechanism Of the Linux kernel.

Train of thought 2: background play silent audio, simulate front desk service, improve the level

Idea 3:1 pixel interface

Idea 4: Start the Service in the Activity’s onDestroy() by sending a broadcast and in the broadcast receiver’s onReceive()

Importance of process, divided into 5 levels: Foreground process Visible process Service process Background process Empty process Foreground process Visible process Service process Background process

What is oom_adj? It is a value assigned by the Linux kernel to each system process to represent the priority of the process, and the process reclamation mechanism determines whether to recycle based on this priority. The more oom_adj a process has, the lower its priority, and the more likely it is to be killed and recycled. The smaller the value is, the higher the priority of the process is, and the less likely it is to be killed. If oom_adj>=0 of common app processes is recycled, oom_adj of system processes may be <0. Some mobile phone manufacturers put these well-known apps into their whitelist to ensure that the process is immortal and improve user experience

Broadcast registration methods and differences

Broadcast There are two registration methods for Broadcast.

  • The first is static registration, which can also become a resident broadcast, which needs to be registered in the AndroidManifest.xml. The registered broadcast is not affected by the page life cycle, even if you exit the page, you can also receive the broadcast. Since this registered broadcast is a resident broadcast, it consumes CPU resources.

  • The second is dynamic registration, and dynamic registration, you register in your code, and this is also called non-resident broadcast, because it’s affected by the life cycle, so when you exit the page, you don’t get broadcast, and we usually use this for updating the UI. This registration method has a higher priority. Finally, you need to unbind, otherwise you will leak memory

Broadcasting is divided into ordered broadcasting and disordered broadcasting.

Broadcast comes in several forms

Normal broadcast: a completely asynchronous broadcast in which all broadcast receivers receive the broadcast message almost at the same time after it is sent, so their order of reception is random.

Orderly broadcast: A simultaneous execution of radio, and on the radio, the same time there will be only one radio receiver can receive the broadcast message, when after the execution of logic of the radio receiver, the radio will continue to pass, so at this time of the radio receiver is sequenced, and a higher priority (priority) radio receiver would receive broadcast messages first. An ordered broadcast can be truncated by a receiver so that subsequent receivers cannot receive it.

Local broadcast: The broadcast can only be transmitted within the application, and the broadcast receiver can only receive the broadcast from the application.

Sticky broadcast: This broadcast persists until a receiver matching the broadcast is registered and receives the broadcast.

Differences between partial broadcasts

BroadcastReceiver: A BroadcastReceiver can broadcast across applications and is implemented by Binder. It supports both dynamic and static registration modes.

LocalBroadcastReceiver: an in-application broadcast device that uses the Handler function and IntentFilter Match function to publish and receive messages. It implements in-application communication with high efficiency and security, and supports only dynamic registration.

OrderedBroadcast: Calls sendOrderedBroadcast() to send. The receivers are sorted in order of priority. If they have the same priority, register first, process the broadcast first and the receiver can truncate and modify the broadcast

ContentProvider

As one of the four components, the ContentProvider is primarily responsible for storing and sharing data. Unlike the file store, the SharedPreferences store, and the SQLite database store, which save data that can only be used by the application, the former allows data to be shared between different applications, and allows you to choose which parts of the data to share. So as to ensure that the privacy data in the program will not have the risk of leakage.

We have a couple of Context objects in our app

Let’s start with an explanation of the source code

/** * Interface to global information about an application environment. This is * an abstract class whose implementation  is provided by * the Android system. It * allows access to application-specific resources and classes, as well as * up-calls for application-level operations such as launching activities, * broadcasting and receiving intents, etc. */ public abstract class Context { /** * File creation mode: the default mode, where the created file can only * be accessed by the calling application (or all applications sharing the * same user ID). * <a href="http://www.jobbole.com/members/[email protected]">@see</a> #MODE_WORLD_READABLE * <a href="http://www.jobbole.com/members/[email protected]">@see</a> #MODE_WORLD_WRITEABLE */ public static final int MODE_PRIVATE = 0x0000; public static final int MODE_WORLD_WRITEABLE = 0x0002; public static final int MODE_APPEND = 0x8000; public static final int MODE_MULTI_PROCESS = 0x0004; }Copy the code

The annotations in the source code explain Context as follows: Context provides an interface to global information about the application environment. It is an abstract class whose execution is provided by the Android system. It allows access to resources and types that are characteristic of the application, and is a context that governs some resources (application environment variables, etc.). That is, it describes information about an application’s environment (the context); Is an abstract class. Android provides a concrete implementation class for this abstract class. It provides access to application resources and classes (including application-level operations such as starting an Activity, broadcasting, receiving an Intent, etc.).

We can see from the diagram above that the specific subclasses of Context in an Application are Activity, Service, and Application. thenNumber of contexts = Number of Activities + Number of Services +1. Of course, if you are careful enough, you may have a question: We often say that the Activity, Service only holds the Context, then Broadcast Receiver, Content Provider?Broadcast Receiver and Content Provider are not subclasses of Context. The Context they hold is passed elsewhereSo it doesn’t count in the total Context.

Application Context startup problem

If we use the ApplicationContext to launch a LaunchMode for standard Activity complains when android. Util. AndroidRuntimeException: Calling startActivity from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? This is because non-activity Context does not have a stack, so the Activity to be started cannot find the stack. The way to solve this problem is to specify the FLAG_ACTIVITY_NEW_TASK bit for the Activity to be started. This creates a new task stack for it when the Activity is started in singleTask mode. All methods of starting an Activity with an Application are not recommended. Service is the same as Application.

How do I get the Context object

1: view. getContext, which returns the Context object of the current View object, usually the Activity object currently being displayed.

2: the Activity getApplicationContext, gets the current Activity in the process of (application) of the Context object, usually we use the Context object, to give priority to the process of the global Context.

4: Actively. this returns the current instance of the Activity. If it is a UI control, use the Activity as the Context object, but the default Toast actually uses the ApplicationContext as well.

How do I avoid memory leaks because of Context

In general, the memory leak caused by Context is almost always when the Context is destroyed, but the destruction failure is caused by reference, and the Context object of Application can be understood as existing with the process, so we summarized the correct posture of using Context:

1: When the Application Context is available and the object has a long life cycle, the Application Context is preferred.

2: Do not allow objects with a lifetime longer than the Activity to hold references to the Activity.

3: Try not to use a non-static inner class in an Activity, because a non-static inner class implicitly holds a reference to an instance of the external class. If you use a static inner class, the external instance reference is held as a weak reference.

The difference between getApplication() and getApplicationContext()

In fact, the object that we get from the program printing the two methods Application itself is a Context, so what we get from getApplicationContext() is an instance of Application itself. The question is, why does Android provide two methods with duplicate functionality when both methods produce the same result?

The two methods are actually quite different in scope. The getApplication() method is very semantically used to retrieve an Application instance, but this method can only be called from activities and services. In most cases, we might want to use an Application in an Activity or Service, but in some other scenario, such as a BroadcastReceiver, we want to get an instance of the Application. This is where you can use the getApplicationContext() method.

Understand the relationship between Activity, View, and Window

An Activity is like a craftsman (control unit), a Window is like a Window (host model), a View is like a Window (display View), a LayoutInflater is like a scissors, and an Xml configuration is like a Window drawing. 1: When an Activity is constructed, it initializes a Window, specifically a PhoneWindow. PhoneWindow has a “ViewRoot”, which is a View or ViewGroup, the original root View. 3: “ViewRoot” adds views one by one through the addView method. For example, TextView, Button, etc. 4: The event listener of these views is received by WindowManagerService and calls back to the Activity function. Such as onClickListener, onKeyDown and so on.

Four launchModes and their usage scenarios

First In First Out stacks and queues

Queue first in first out, stack first in last out “qualifying” insert and delete operations. A stack is a linear table that is restricted to insert and delete operations only at one end of the table. Queues are linear tables that are restricted to inserts at one end and deletes at the other. Different speeds for traversing data

Standard Mode This is the default mode. Each time an Activity is activated, an instance of the Activity is created and placed in the task stack. Usage scenarios: Most activities. If an instance of the Activity happens to exist at the top of the task stack, the instance is reused (onNewIntent() is called), otherwise a new instance is created and placed at the top of the stack, even if an instance of the Activity already exists, as long as it is not on the top of the stack. New instances are created. Usage scenarios such as news or reading App content page. The singleTask pattern reuses an instance of the Activity if it already exists on the stack (onNewIntent() is called for the instance). When reused, the instance will go back to the top of the stack, so the instance on top of it will be moved off the stack. If the instance does not exist on the stack, a new instance will be created and put on the stack. Usage Scenarios For example, the main page of a browser. No matter how many apps you launch the browser from, the home screen is launched only once. The rest of the time, the onNewIntent is used and all other pages above the home screen are cleared. The singleInstance pattern creates an instance of the Activity on a new stack and shares it with multiple applications. Once an Activity instance of this pattern already exists on a stack, any application that reactivates the Activity will reuse that instance on the stack (by calling the instance’s onNewIntent()). The effect is the same as multiple apps sharing an app, and whoever activates the Activity enters the same app. Usage scenarios For example, alarm notification. Separate alarm notification from alarm Settings. A -> B (singleInstance) -> C (singleInstance)

Data is stored

What methods of data persistence does Android provide?

File storage: Write and read files in the same way as Java I/O programs.

SharedPreferences storage: A lightweight data store used to store simple configuration information, essentially storing key-value data pairs based on XML files.

SQLite database storage: a lightweight relational database, its operation speed is very fast, occupies very few resources, in the storage of a large number of complex relational data can be used.

ContentProvider: One of the four components used for data storage and sharing. Not only can different applications share data, but also can choose which part of the data to share, to ensure that the privacy of the data in the application is not at risk of leakage.

SharePreferences related issues

  1. SharePreferences is a lightweight data store for storing simple configuration information such as int, String, Boolean, float, and long. Since the system has a cache policy for SharedPreferences reads/writes, that is, there is a cache of the file in memory, the reads/writes can become unreliable and even lose data in multi-process mode.

  2. Context. GetSharedPreferences () began to track, you can go to ContextImpl getSharedPreferences (), SharedPreferencesImpl, an implementation class for SharedPreferences, turns out to be thread safe because you can see a large number of synchronized reads and writes in the code

  3. Since memory cannot be shared between processes, each process has a separate instance of SharedPreferences, which makes it unsafe for multiple processes to share data through SharedPreferences. This problem can only be solved by other means of communication between multiple processes or by using SharedPreferences while ensuring that SharedPreferences data is not manipulated at the same time.

SharePreferences precautions and optimization methods

  1. The first getSharePreference will read the disk file, read it asynchronously, write it to memory, and all subsequent getSharePreference will take it from memory.
  2. All GET /set requests are stuck until the first read is complete, so there is an ANR risk for the first read.
  3. All gets are read from memory.
  4. Commits are written to memory and disk. The difference between apply and COMMIT is that

Apply is memory synchronization and then disk asynchronous write tasks are placed on a single-threaded queue waiting to be called. Void commit Memory synchronization simply waits for the disk write to complete before returning true or false. Starting with Android N, MODE_WORLD_READABLE & MODE_WORLD_WRITEABLE are no longer supported. Once specified, an exception is thrown. Also don’t use MODE_MULTI_PROCESS to get abandoned sooner or later. 8. All data is written to disk at one time for each commit/apply. That is, there is no concept of incremental write. Therefore, individual files should not be too large or performance will be seriously affected.

It is suggested to use the third-party MMKV of wechat to replace SharePreference

SP source code parsing

SQLite related issues

  • Batch operations using transactions:

Use the beginTransaction() method of SQLiteDatabase to open a transaction, the batch operation SQL statement into SQLiteStatement and batch operation, after the end of endTransaction()

  • Close Cursor in time to avoid memory leaks

  • Asynchrony of time-consuming operations: Database operations are local I/OS and are time-consuming. It is recommended that these time-consuming operations be processed in asynchronous threads

  • Capacity adjustment of ContentValues: HashMap is used to store key-value data inside ContentValues. The initial capacity of ContentValues is 8, and the capacity is doubled during expansion. Therefore, it is recommended to measure the content to be filled in ContentValues and set a reasonable initial capacity to reduce unnecessary internal expansion operations

  • Using indexes to speed up retrieval: Indexes are recommended for large query operations and services with high query requirements