The four major components of Android

Table of contents

1.Activity

2.Service与intentService

3.LocalBroadcastManager的BroadcastReceiver

4.ContentProvider


Activity

        Activity is an Android application component that provides screens for interaction. Each Activity gets a window for drawing its user interface. The window can fill the screen or be smaller than the screen and float on top of other windows.

        An application is usually composed of multiple activities that are loosely related to each other. Generally, an Activity in the application is designated as the main activity, which means that the Activity is presented to the user when the application is first launched.

To set Activity as the main activity, as shown in the code below, you need to add the following content to the AndroidManifest file

<application>
     ....
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

</activity>
        ....
</application>

In Android, Activity has four basic states:

1.Active/Runing After a new Activity is started and pushed into the stack, it is at the front of the screen and at the top of the stack. At this time, it is in an activated state that is visible and can interact with the user.

2.Paused is the state when the Activity is covered by another transparent or Dialog style Activity. At this point it remains connected to the window manager and the system continues to maintain its internal state, so it is still visible, but it has lost focus and cannot be interacted with by the user.

3.Stoped When the Activity is covered by another Activity, loses focus and is not visible, it is in the Stopped state.

4.Killed Activity is in the Killed state when it is killed and recycled by the system or is not started.

        If an activity is in a stopped or suspended state, it will be finished or killed when the system lacks memory. In this abnormal situation, the system will call the onSaveInstance() method to save the information before killing or ending. At the same time, when the Activity is moved to the foreground, the Activity will be restarted and the onRestoreInstance() method will be called to load the retained information. Keep it as it is.

        When an Activity instance is created, destroyed, or starts another Activity, it transitions between these four states. The occurrence of this transition depends on the actions of the user program. The following figure illustrates the timing and conditions for Activity to transition between different states.


Service与intentService

Service Introduction

  • A Service is an application component that performs long-running operations in the background without providing an interface. Services can be started by other app components and will continue to run in the background even if the user switches to another app. Additionally, components can interact with services by binding to them, and even perform inter-process communication (IPC).
  • For example, a service can handle network transactions, play music, perform file I/O, or interact with content providers in the background.
  • [1] Service is a solution for background running of programs in Android. It is very suitable for performing tasks that do not require interaction with the user and require long-term running.
  • [2] Service does not run in a child thread by default, nor does it run in an independent process. It also executes in the UI thread. Therefore, do not perform time-consuming operations in Service unless you are in Service. Created sub-threads to complete time-consuming operations
  • [3] The operation of Service does not depend on any user interface. Even if the program is switched to the background or the user opens another application, Service can still run normally. This is exactly the usage scenario of Service. When an application process is killed, all services that depend on the process will also stop running.

 Service is basically divided into two forms:

[1] Startup state When an application component (such as Activity) starts the service
by calling startService() , the service is in the "started" state. Once started, the service can run in the background indefinitely, even if the component that started the service has been destroyed. The service cannot be stopped unless manually called. A started service usually performs a single operation and does not return the result to the call. square.
 
[2] Binding state
When an application component is bound to a service by calling bindService() , the service is in the "bound" state. A bound service provides a client-server interface that allows components to interact with the service, send requests, get results, and even perform these operations across processes using inter-process communication (IPC). The bound service only runs when bound to another application component. Multiple components can be bound to the service at the same time, but when all are unbound, the service will be destroyed.


IntentService

  • An asynchronous framework that encapsulates HandlerThread and Handler.
  • It is a special Service, inherited from Service, and is an abstract class. You must create a subclass before it can be used.
  • Can be used to perform time-consuming tasks in the background. The tasks will automatically stop after execution.
  • It has high priority (for service reasons), and its priority is much higher than that of a simple thread. It is suitable for high-priority background tasks and is not easily killed by the system.
  • The startup method is the same as Service.
  • It can be started multiple times, and each time-consuming operation will be executed in the onHandleIntent callback method of IntentService in the form of a work queue.
  • Serial execution.

Notice:

  1. If there is only one task, time-consuming operations can be performed.
  2. If there are many tasks, since the internal HandlerThread executes tasks serially, time-consuming operations will block the execution of subsequent tasks.

The difference between Service and IntentService

  • IntentService inherits from Service
  • The IntentService task will automatically stop after execution.
  • IntentService and Service have the same priority, higher than Thread.
  • Service is in the main thread and cannot directly perform time-consuming operations; IntentService has a HandlerThread inside, which can perform time-consuming operations.

LocalBroadcastManager的BroadcastReceiver

BroadcastReceiver Security Issues
The original intention of BroadcastReceiver design is to facilitate communication between applications and systems, between applications, and within applications from a global perspective. Therefore, BroadcastReceiver has security issues for a single application (malicious program scripts continue to remove Send the broadcast you receive). In order to solve this problem, LocalBroadcastManager came into being.

LocalBroadcastManager
LocalBroadcastManager is a tool provided by the Android Support package for sending Broadcast between different components within the same application. LocalBroadcastManager is also called a local notification manager. The advantage of this notification is that it is highly secure and efficient. It is suitable for local communication and can be used to update the UI instead of Handler.

Advantages:
1. Since broadcast data is spread within the scope of this application, you don’t have to worry about privacy data leakage.
2. Don’t worry about other applications forging broadcasts, causing security risks.
3. It is more efficient than sending global broadcasts within the system.

Usage of LocalBroadcastManager

Creation of LocalBroadcastManager object
 

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance( this ) ;

Register a broadcast receiver
 

LocalBroadcastManager.registerReceiver( broadcastReceiver , intentFilter );

Send broadcast
 

LocalBroadcastManager.sendBroadcast( intent ) ;

Unregister a broadcast receiver
 

LocalBroadcastManager.unregisterReceiver( broadcastReceiver );

LocalBroadcastManager partial source code analysis

private static LocalBroadcastManager mInstance;

public static LocalBroadcastManager getInstance(Context context) {
    synchronized (mLock) {
        if (mInstance == null) {
            mInstance = new LocalBroadcastManager(context.getApplicationContext());
        }
        return mInstance;
    }
}

private LocalBroadcastManager(Context context) {
    mAppContext = context;
    mHandler = new Handler(context.getMainLooper()) {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_EXEC_PENDING_BROADCASTS:
                    executePendingBroadcasts();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    };
} 

Two points can be seen from this part of the source code:

1. When obtaining the LocalBroadcastManager object instance, the singleton mode is used here. And the Context passed in from the outside is converted into ApplicationContext, which effectively avoids the problem of memory leakage of the current Context. This is worth learning when we design the singleton pattern framework. You can learn a lot by looking at the source code.

2. A Handler is created in the LocalBroadcastManager constructor. It can be seen that LocalBroadcastManager essentially sends and receives messages through the Handler mechanism.

When creating the Handler, context.getMainLooper() is used, indicating that the Handler is created in the Android main thread. The broadcast receiver will receive messages in the Android main thread, so we must not do it in the broadcast receiver. Time-consuming operation to avoid blocking the UI.

package com.app;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    private LocalBroadcastManager localBroadcastManager ;
    private MyBroadcastReceiver broadcastReceiver ;
    private IntentFilter intentFilter ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //注册广播接收器
        localBroadcastManager = LocalBroadcastManager.getInstance( this ) ;
        broadcastReceiver = new MyBroadcastReceiver() ;
        intentFilter = new IntentFilter( "myaction") ;
        localBroadcastManager.registerReceiver( broadcastReceiver , intentFilter );

        //在主线程发送广播
        Intent intent = new Intent( "myaction" ) ;
        intent.putExtra( "data" , "主线程发过来的消息" ) ;
        localBroadcastManager.sendBroadcast( intent ) ;

        new Thread(new Runnable() {
            @Override
            public void run() {
                //在子线程发送广播
                Intent intent = new Intent( "myaction" ) ;
                intent.putExtra( "data" , "子线程发过来的消息" ) ;
                localBroadcastManager.sendBroadcast( intent ) ;
            }
        }).start(); ;

    }

    private class MyBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction() ;
            if ( "myaction".equals( action )){
                Log.d( "tttt 消息:" + intent.getStringExtra( "data" )  , "线程: " + Thread.currentThread().getName() ) ;
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        //取消注册广播,防止内存泄漏
        localBroadcastManager.unregisterReceiver( broadcastReceiver );
    }
}

operation result:

D/tttt message: message sent by the main thread: thread: main
D/tttt message: message sent by the child thread: thread: main

It can be seen that the onReceive method of the broadcast receiver runs on the main thread.


Notes
Although LocalBroadcastManager also receives messages through BroadcastReceiver, there are still many differences between them.

1. LocalBroadcastManager can only register broadcasts through code registration. Traditional broadcasts can be registered in two ways: code and xml.
2. After registering the broadcast with LocalBroadcastManager, you must remember to cancel monitoring. This step can effectively solve the problem of memory leaks.
3. For broadcasts registered with LocalBroadcastManager, you must use LocalBroadcastManager.sendBroadcast(intent) when sending broadcasts; otherwise you will not receive the broadcasts. Traditional method of sending broadcast: context.sendBroadcast( intent );


ContentProvider

One of the four major components of Ancroid is the content provider.

effect:


Data interaction & sharing between processes , that is, cross-process communication

 


principle:

  • ContentProviderThe underlying mechanism is  the mechanism used AndroidinBinder
  • About Binder:definition

 If you want to know more about the Binder mechanism , you can read this article

Android cross-process communication: Detailed explanation of the Binder mechanism principle with pictures and texts_Carson's blog to teach you Android-CSDN blog

Specific use:

 


Uniform Resource Identifier (URI) 

  • The external process  URI finds the corresponding ContentProvider & data and then performs data operations.
  • URIDivided into system presets & customizations, corresponding to system built-in data (such as address book, schedule, etc.) and custom databases:

// 设置URI
Uri uri = Uri.parse("content://com.carson.provider/User/1") 
// 上述URI指向的资源是:名为 `com.carson.provider`的`ContentProvider` 中表名 为`User` 中的 `id`为1的数据

// 特别注意:URI模式存在匹配通配符* & #

// *:匹配任意长度的任何有效字符的字符串
// 以下的URI 表示 匹配provider的任何内容
content://com.example.app.provider/* 
// #:匹配任意长度的数字字符的字符串
// 以下的URI 表示 匹配provider中的table表的所有行
content://com.example.app.provider/table/# 


MIME data types

  • Function: Specify a file with a certain extension to be opened by a certain application.
    For example, the specified .htmlfile textshould be opened by an application, and the specified .pdffile should be flashopened by an application.

ContentProvider class

ContentProvider supports organizing data in the form of tables (mainly) and files

Specific use:

  • The essence of data shared between processes is: adding, deleting, obtaining & modifying (updating) data
  • <-- 4个核心方法 -->
      public Uri insert(Uri uri, ContentValues values) 
      // 外部进程向 ContentProvider 中添加数据
    
      public int delete(Uri uri, String selection, String[] selectionArgs) 
      // 外部进程 删除 ContentProvider 中的数据
    
      public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
      // 外部进程更新 ContentProvider 中的数据
    
      public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,  String sortOrder)  
      // 外部应用 获取 ContentProvider 中的数据
    
    // 注:
      // 1. 上述4个方法由外部进程回调,并运行在ContentProvider进程的Binder线程池中(不是主线程)
     // 2. 存在多线程并发访问,需要实现线程同步
       // a. 若ContentProvider的数据存储方式是使用SQLite & 一个,则不需要,因为SQLite内部实现好了线程同步,若是多个SQLite则需要,因为SQL对象之间无法进行线程同步
      // b. 若ContentProvider的数据存储方式是内存,则需要自己实现线程同步
    
    <-- 2个其他方法 -->
    public boolean onCreate() 
    // ContentProvider创建后 或 打开系统后其它进程第一次访问该ContentProvider时 由系统进行调用
    // 注:运行在ContentProvider进程的主线程,故不能做耗时操作
    
    public String getType(Uri uri)
    // 得到数据类型,即返回当前 Url 所代表数据的MIME类型
    
  • AndroidProvides built-in default data for common data (such as address book, schedule, etc.)ContentProvider
  • But it can also be customized according to needs ContentProvider, but the above 6 methods must be rewritten.
  • ContentProviderThe class does not interact directly with the external process, but through ContentResolver the class

ContentResolver class

Unified management  ContentProviderof operations between different rooms

  • That is,  URI you can operate ContentProvider data in different
  • External processes  interact ContentResolverwith classes through classesContentProvider

Why interact with the ContentProvider class through the ContentResolver class instead of accessing the ContentProvider class directly?

answer:

  • Generally speaking, an application uses multiple ContentProviders. If you need to understand the different implementations of each ContentProvider to complete data interaction, the operation cost is high and difficult.
  • Therefore, a ContentResolver class is added to the ContentProvider class to uniformly manage all ContentProviders.
     

ContentResolver The class provides ContentProvider4 methods with the same name & function as the class

// 外部进程向 ContentProvider 中添加数据
public Uri insert(Uri uri, ContentValues values)  

// 外部进程 删除 ContentProvider 中的数据
public int delete(Uri uri, String selection, String[] selectionArgs)

// 外部进程更新 ContentProvider 中的数据
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)  

// 外部应用 获取 ContentProvider 中的数据
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

Android Three auxiliary ContentProvidetool classes are provided:

  • ContentUris(操作URI)
  • UriMatcher(1.在ContentProvider中注册URI    2.根据URI去匹配ContentProvider中对应的数据库。)
  • ContentObserver(观察URI引起ContentProvider的数据变化&通知外界(即访问该数据访问者))

For more details, see this article:

Carson takes you to learn Android: Everything you need to know about ContentProvider is here! _Carson takes you to learn Android's blog-CSDN blog_contentprovider


 The above are the four major components of Android. This is just a rough document. For details, you can follow this blogger.

@Carson takes you to learn Android

It’s not easy to make, thank you for watching!

Guess you like

Origin blog.csdn.net/qq_62277763/article/details/127989155