主頁 > 移動端開發 > Android應用程式建立與AMS服務之間的通信程序

Android應用程式建立與AMS服務之間的通信程序

2020-12-09 14:34:42 移動端開發

?????Android應用程式建立與AMS服務之間的通信程序


Android四大組件原始碼實作詳解系列博客目錄:

Android應用行程創建流程大揭秘
Android四大組件之bindService原始碼實作詳解
Android四大組件之Activity啟動流程原始碼實作詳解概要
Activity啟動流程(一)發起端行程請求啟動目標Activity
Activity啟動流程(二)system_server行程處理啟動Activity請求
Activity啟動流程(三) Activity Task調度演算法復盤分析
Activity啟動流程(四)Pause前臺顯示Activity,Resume目標Activity
Activity啟動流程(五)請求并創建目標Activity行程
Activity啟動流程(六)注冊目標Activity行程到system_server行程以及創建目標Activity行程Application
Activity啟動流程(七)初始化目標Activity并執行相關生命周期流程
Android應用程式建立與AMS服務之間的通信程序

本篇博客撰寫思路總結和關鍵點說明:

在這里插入圖片描述

為了更加方便的讀者閱讀博客,通過導讀思維圖的形式將本博客的關鍵點列舉出來,從而方便讀者取舍和閱讀!



引言

??Android四大組件作為Android整個應用層框架的基石,其在Android中的地位是毋庸置疑的,而AMS(這里將ActivityManagerService簡稱AMS)做為四大組件啟動,管理的核心服務卻是運行在system_server行程中的,而我們的四大組件的啟動和管理,更有甚者我們四大組件所在應用程式的創建都離不開和AMS服務之間的跨行程互動程序,那么這兩個行程之間是怎么進行跨行程通信的呢,我想如果對于Android有一定了解的讀者肯定會脫口而出通過Binder通信,是的應用程式和AMS服務之間正是通過Binder進行通信的!而我們今天的博客將會重點分析二者之間是如何建立Binder通信邏輯的,即:

我們知道Binder通信有一個特點就是通常只能Binder客戶端請求Binder服務端,而不能反過來(注意這里的措辭是通常)!所以通常Binder客戶端和服務端之間想建立相互通信的關系,會借助匿名Binder,而我們這里的AMS和應用程式之間也是如此!

  • Android應用程式以及關聯的四大組件建立和AMS的Binder通信
  • AMS建立和應用程式及四大組件的Binder通信

注意:本篇的介紹是基于Android 7.xx平臺為基礎的,其中涉及的代碼路徑如下:

frameworks/base/services/core/java/com/android/server/am/
  --- ActivityManagerService

frameworks/base/core/java/android/app/
	---Activity.java
	---ActivityThread
	---ApplicationThreadNative.java
	---IApplicationThread.java
	---ActivityManagerNative.java
	---IActivityManager.java

并且在后續的原始碼分析程序中為了簡述方便,會將做如下簡述:

  • ApplicationThreadProxy簡稱為ATP
  • ActivityManagerProxy簡稱為AMP
  • ActivityManagerService簡稱為AMS
  • ActivityManagerNative簡稱AMN
  • ApplicationThreadNative簡稱ATN

在正式開始分析前,我們先奉上Android應用程式和AMS之間跨行程Binde通信互動圖,也許下面的圖就能給讀者靈感,不待我分析就知道了今天的主題Android應用程式建立與AMS服務之間的通信程序了,
在這里插入圖片描述



一.Android應用程式以及關聯的四大組件建立和AMS的Binder通信

在正式開始相關的的分析之前,將要涉及到涉及到Context的繼承關系類圖,從下面的類圖中可以看出,Context是一個介面(提供了很多的介面方法),ContextImp和ContextWrapper都是其實作類,我們常用的Activity、Service、Application都直接或間接繼承自ContextWrapper,

在這里插入圖片描述


1.1 Android應用層獲取Framework層AMS核心服務對外介面類ActivityManager

??AMS做為Android Framework層的Binder核心服務,它被注冊到了servicemanager服務大管家里面,并且也和其它核心服務一樣在Android Framework的框架層提供了對應的SDK介面供應用程式呼叫AMS服務,而我們這里以在應用程式的Activity或者其子類中獲取AMS服務對外提供介面類為例說明:


ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

注意這里我們只是為了演示,其實Context背景關系已經為了提供了關于使用AMS服務的相關封裝介面,譬如startActivity()等

這里我們通過上面的類圖關系知道getSystemService()方法最侄訓呼叫到ContextThemeWrapper類的getSystemService中,原始碼如下:

//[ContextThemeWrapper.java]
    @Override
    public Object getSystemService(String name) {
        if (LAYOUT_INFLATER_SERVICE.equals(name)) {
            if (mInflater == null) {
                mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
            }
            return mInflater;
        }
        return getBaseContext().getSystemService(name);
    }

	//[ContextWrapper.java]
    public Context getBaseContext() {
        return mBase;//注意這里的mBase指向了ContextImpl類
    }

從上面的代碼可以看到getSystemService()方法最終都呼叫到了ContextImpl類中,而至于mBase為什么指向了ContextImpl實體,這里就不過多篇幅分析了可以參見博客初始化目標Activity并執行相關生命周期流程的2.3章節,這里我們直接來看ContextImpl中getSystemService()的實作,如下:

//[ContextImpl.java]
    @Override
    public Object getSystemService(String name) {
        return SystemServiceRegistry.getSystemService(this, name);
    }

這里又來了一個SystemServiceRegistry類,我們接著繼續分析看看它的處理邏輯!

//[SystemServiceRegistry.java]
    private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
            new HashMap<Class<?>, String>();
    private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
            new HashMap<String, ServiceFetcher<?>>();
    public static Object getSystemService(ContextImpl ctx, String name) {
        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
        return fetcher != null ? fetcher.getService(ctx) : null;
    }

好像很簡單額,直接從SYSTEM_SERVICE_FETCHERS哈希串列中根據服務名稱進行查找,這里我們看下SYSTEM_SERVICE_FETCHERS是啥時候被填充的,我們接著查找:

//[SystemServiceRegistry.java]
    private static <T> void registerService(String serviceName, Class<T> serviceClass,
            ServiceFetcher<T> serviceFetcher) {
        SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
        SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
    }

可以看到在registerService()方法中注冊了一系列的服務,我接著繼續查找看看那里呼叫了它!

//[SystemServiceRegistry.java]
    static {
	    // Not instantiable.
	    private SystemServiceRegistry() { }
    	...
    	registerService(xxx);
    	registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,
                new CachedServiceFetcher<ActivityManager>() {
            @Override
            public ActivityManager createService(ContextImpl ctx) {
                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
            }});
            
}

這里我們可以看到SystemServiceRegistry類的static靜態方法區中注冊了一系列的服務,而我們的ActivityManager實體物件也被注冊到了里面,支持我們就可以使用AMS相關的服務了,而其它的Android Framework層核心服務也數通過上述方法進行注冊,然后對外提供的,

不知道細心的讀者注意到了沒有這里的SystemServiceRegistry類,只有一個私有構造方法,那么說明他不能被實體化,那它是怎么被實體化的呢,或者說是怎么被加載然后執行static的靜態區的注冊方法呢,這個就要說我們我們的zygote預加載機制了,在Android Zygote行程啟動原始碼分析指南的的2.3章節我們知道zygote行程會呼叫preload()方法中會通過反射預加載一些類,而這其中就包括我們的SystemServiceRegistry,而我們的Android應用程式行程是由zygote行程范訓的所以繼承了zygote行程資源,所以它預加載的SystemServiceRegistry也被我們繼承到了,

而我們知道zygote行程預加載的claess被定義在frameworks/base/preloaded-classes中,我們簡單看下就找到了SystemServiceRegistry身影,如下:

在這里插入圖片描述


1.2 Android應用層通過外介面類ActivityManager使用AMS服務

??通過前面的一頓操作,我們獲取到了AMS服務對外的介面類ActivityManager,在正式開始分析Android應用程式是怎么通過它使用AMS服務之間,我們先來看看AMS的整體類圖框架圖,如下:

在這里插入圖片描述
好了前面1.1章節我們最后獲取到了ActivityManager的實體物件,我們來看看其構造方法,如下:

//[ActivityManager.java]
    /*package*/ ActivityManager(Context context, Handler handler) {
        mContext = context;//感覺啥也沒有做,根本沒有和AMS搭上半毛錢關系
        mHandler = handler;
    }

尼瑪,這里的ActivityManager感覺和AMS服務沒有搭上半毛錢關系啊,是不是搞錯了啊!當然不是了,這里我們隨意抽取AcivityManager中的一個方法來看看,如下:

//[ActivityManager.java]
    public List<RunningServiceInfo> getRunningServices(int maxNum)
            throws SecurityException {
        try {
            return ActivityManagerNative.getDefault()
                    .getServices(maxNum, 0);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

這里我們終于看到老熟人AMN了,這里牽涉到一個重要的方法AMN.getDefault(),其實它在我們的博客中 Android Binder框架實作之Java層獲取Binder服務原始碼分析已經有詳細的介紹和分析了,但是為了博客的連貫性還是簡單過下(主要是為了不太熟悉的小伙伴們),

	//ActivityManagerNative.java
    static public IActivityManager getDefault() {
        return gDefault.get();
    }

這里的gDefault是Singleton物件實體,而Singleton我們可以看到是一個模板類物件,并且提供了一個單例方法,其定義如下:

//Singleton.java
public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {//采用單例模式
                mInstance = create();
            }
            return mInstance;
        }
    }
}

我們將IActivityManager帶入Singleton,得到如下的create方法程序:

	//ActivityManagerNative.java
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
        	//此處等價于IBinder b = new BinderProxy(new BpBinder(handle));
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
			//此處等價于IActivityManager am = new ActivityManagerProxy(new BinderProxy(new BpBinder(handle)))
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

	//注意此處我們的入參是BinderProxy型別,所以會走代理端
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
		//即會走到此處
        return new ActivityManagerProxy(obj);
    }

這里即最終經過層層轉換得到了AMS服務的代理端ActivityManagerProxy,進而借助它完成對AMS服務的RPC請求,


1.3 Android應用程式以及關聯的四大組件建立和AMS的Binder通信小結

??至此Android應用程式以及關聯的四大組件建立和AMS的Binder通信就已經建立了,其主要核心流程就是先通過Context背景關系環境獲取ActivityManager,然后ActivityManager借助AMS的代理端AMP來和AMS服務通信從而達到呼叫AMS服務的功能,而這里最最重要的就是AMN.getDefault()的呼叫邏輯了,這里我們對其小結一下:

  • AMN.getDefault()最侄訓取了AMS的遠程Binder代理端AMP
  • AMS的Binder通信程序中提供了一個IActivityManager服務業務層介面,AMP類與AMS類都實作了IActivityManager介面方法,區別不同給的是AMS端顯示了真正的具體服務,而AMP端是封裝了相關的通信傳輸邏輯,AMP作為Binder通信的服務代理端,而AMS作為Binder通信的服務端物體,根據Android Binder框架實作之Java層Binder服務跨行程呼叫原始碼分析,AMP.xxx()最終呼叫AMS.xxx(),整個流程圖如下:
    在這里插入圖片描述

至此我們就建立了一條如下的通信道路線完成Android應用程式以及關聯的四大組件建立和AMS的Binder通信

在這里插入圖片描述

這里我們需要注意的是其實對四大組件的常規操作,我們的Context背景關系環境已經為我么封裝好了相關的呼叫介面,譬如startActivity(),startService()等!但是其核心還是獲取AMS服務的代理端AMP,只是省略了獲取ActivityManager的流程罷了!




二.AMS建立和Android應用程式以及關聯的四大組件之間的Binder通信

??我們知道Android應用程式行程通常是AMS服務請求zygote行程fork出來的,Android應用程式被fork出來以后經過一些列的初始化最侄訓通過反射呼叫到ActivityThread.main()方法中(如果對此處邏輯不是很清楚的,詳見博客請求并創建目標Activity行程),而我們AMS建立和Android應用程式以及關聯的四大組件之間的Binder通信正是在執行main()方法中進行的,

//[ActivityThread.java]
public static void main(String[] args) {
    ...
    Environment.initForCurrentUser();
    ...
    Process.setArgV0("<pre-initialized>");
    //創建主執行緒looper
    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    //attach到系統行程AMS服務,從而使AMS建立和應用程式的通信通道
    thread.attach(false);//詳見章節2.1

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    //主執行緒進入回圈狀態
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

2.1 ApplicationThread簡介

??在正式開始上述Binder通道建立之前,我們有必要來先了解了解ApplicationThread類實作了IApplicationThread介面,這里我們先來簡單看下IApplicationThread的定義,如下:

//[IApplicationThread.aidl]
public interface IApplicationThread extends IInterface {
    void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, boolean dontReport) throws RemoteException;
    void scheduleStopActivity(IBinder token, boolean showWindow,
            int configChanges) throws RemoteException;
}

可以看到IApplicationThread定義的方法很多,絕大不是是和Android四大組件生命周期調度有關的,我們接著來看ApplicationThread類,它是一個匿名Binder類,其類圖關系圖如下:

如果對Binder特別是匿名/實名Binder還沒有了解的讀者強烈建議先閱讀一下該篇以及一系列的博客Android Binder框架實作之何為匿名/實名Binder,通過前面的博客我們應該知道匿名Binder有兩個比較重要的用途:
一個是拿到Binder代理端后可跨Binder呼叫物體端的方法介面(我們這里主要利用了這個功能 )
另一個作用便是在多個行程中標識同一個物件

在這里插入圖片描述

這里的IApplicationThread與IActivityManager的Binder通信原理一樣,ATP作為Binder通信的客戶端,ATN作為Binder通信的服務端,其中ApplicationThread繼承ATN類,覆寫其中的部分方法,


2.2 注冊目標Activity行程到system_server建立AMS和它的Binder通信

??通過前面的章節我們了解匿名Binder服務ApplicationThread,而本章節將要分析它是怎么被實名Binder傳遞到system_server行程中然后建立起AMS和它的通信邏輯的,其核心的架構思想如下圖所示:

在這里插入圖片描述

2.2.1 ActivityThread.attach(…)

??其實對于該方法,如果有閱讀過Android系統啟動之system_server行程創建大揭秘的小伙們應該不會陌生了,在system_server行程啟動的流程中也會呼叫它只是傳入的引數為true,而我們此時傳入的引數為false而已!用以區別是system_server行程發起的系結還是普通應用行程發起的系結,

//[ActivityThread.java]
	final ApplicationThread mAppThread = new ApplicationThread();
    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
			...
			// 設定行程名,此時,還沒有ApplicationInfo,所以用<pre-initialized>來命名應用行程
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            ...
			//獲取AMS服務端的遠程代理物件AMP
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
            	//通過Binder遠程呼叫AMS的attachApplication方法
                mgr.attachApplication(mAppThread);//詳見章節
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
			...
        } else {//system_server行程會進入此分支

        }

        DropBox.setReporter(new DropBoxReporter());
		//為ViewRootImpl注冊Config回呼介面
        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
			...
        });
    }

上述方法執行的邏輯并不是很復雜,其主要就是兩點:

  • 獲取AMS服務的遠程代理端AMP
  • 接著通過AMP借助Binder呼叫AMS的方法attachApplication,注意這里傳遞的mAppThread是一個匿名Binder實體,因此可以作為跨行程傳遞的引數,這里的mAppThread物件存在于應用行程,但會被傳遞到系統行程,在系統行程看來,此時的mAppThread就是操作應用行程的一個通信工具,后續,系統行程system_server如果想要向應用行程發起跨行程呼叫,也都需要通過mAppThread這個物件來完成相關的調度,

并且關于上述的執行邏輯我們在Android四大組件之Activity啟動流程原始碼實作詳解(一)中2.4章節已經有過詳細的分析了,這里就不詳細贅述了,并且如果小伙們對于什么是匿名Binder以及怎么傳遞的有不了解的小伙們,這篇博客Android Binder框架實作之何為匿名/實名Binder有詳細分析就不過多歪歪了!

關于上述整個Binder IPC呼叫流程,可以使用如下偽代碼來簡述:

AMP.attachApplication(...)---> 
BinderProxy.transact(...) --->
BpBinder.transact(...)--->
binder驅動傳輸--->
JavaBBinder.onTransact(...)--->
AMN.onTransact(..)--->
AMN.attachApplication(...) --->
AMS.attachApplication(...) --->

2.2.2 AMS.attachApplication(…)系統system_server行程處理attachApplication請求

??在這里AMS回應了目標Activity行程的attachApplication系結請求,注意此時的attachApplication是執行在Binder執行緒中的,

//[ActivityManagerService.java]
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
        	//獲取呼叫行程端pid
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            //attachApplicationLocked進行進一步處理
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }

上述方法比較簡單,接著呼叫attachApplicationLocked進行下一步的處理,注意此時多傳入了一個引數pid,并且這里還有一點主要注意的是此時的引數型別IApplicationThread已經變成了匿名Binder的代理端了ATP了,IApplicationThread它串聯起了AMS對App行程的生命周期及其其它的控制,

我們接著繼續分析,attachApplicationLocked原始碼數量有點多啊(沒有啥的、我們只關心我們所關心的)!

//[ActivityManagerService.java]
   private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {


        ProcessRecord app;
        long startTime = SystemClock.uptimeMillis();
        /*
         	根據PID映射應用行程的ProcessRecord物件
         	那么此處的ProcessRecord是什么時候創建并加入到mPidsSelfLocked中的呢,這個在該系列博客的五中有詳細描述
        */
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }

    	...    
		//將目標Activity行程的IApplicationThread匿名Binder代理端系結到ProcessRecord物件
        app.makeActive(thread, mProcessStats);
        /****************************************************/
        //這里為了演示方便,直接給出原始碼
        	//[ProcessRecord.java]
		    public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
		        if (thread == null) {
					...
		        }
		        thread = _thread;
		    }        
        /****************************************************/
		
		//繼續進行其它的對ProcessRecord的賦值
        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        app.forcingToForeground = null;
        updateProcessForegroundLocked(app, false, false);
        app.hasShownUi = false;
        app.debugging = false;
        app.cached = false;
        app.killedByAm = false;




		...
        try {
			...
			//省略debug和性能優化等相關配置的代碼,這里就不贅述了

			//這里又是老熟人了,一路分析過來見過很多次了,此處發起跨行程呼叫,將一堆的資訊傳遞給目標Activity應用行程
			//立即使用了傳遞過來的匿名Binder,呼叫到了ActivityThread中
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                                   mCoreSettingsObserver.getCoreSettingsLocked());//詳見第二大章節
            updateLruProcessLocked(app, false, null);
  			...
        } catch (Exception e) {//例外處理
 			...
        }

        return true;
    }

我們這里只重點關心IApplicationThread 代理端的處理,在傳遞到AMS服務以后將其保存到了每個應用行程在AMS服務端的記錄ProcessRecord的thread中,從而AMS后續可以繼續使用該Binder代理端來對Android應用程式和四大組件進行相關的調度,這不后面立即來了一個thread.bindApplication的調度,當然AMS服務中并不單單只有此處的呼叫,我們簡單搜索一下能發現許多,如下:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:2107:                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:2855:                            procs.add(app.thread.asBinder());
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:4289:                    app.thread.scheduleTrimMemory(level);
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:4723:            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:5372:                app.thread.asBinder() == thread.asBinder()) {
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:6089:                        app.thread.scheduleSuicide();
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:11625:                                        app.thread.scheduleInstallProvider(pi);
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:12579:                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:15464:                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:17100:                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:19295:                            app.thread.scheduleConfigurationChanged(configCopy);
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:20416:                    app.thread.scheduleLowMemory();
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:20418:                    app.thread.processInBackground();
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:20785:                    app.thread.setProcessState(app.repProcState);
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:21431:                            app.thread.scheduleTrimMemory(curLevel);
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:21468:                            app.thread.scheduleTrimMemory(
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:21486:                                app.thread.scheduleTrimMemory(level);
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:21497:                            app.thread.scheduleTrimMemory(fgTrimLevel);
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:21523:                            app.thread.scheduleTrimMemory(
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:21657:                        + (app.thread != null ? app.thread.asBinder() : null)
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java:21663:                            app.thread.scheduleExit();
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java:1343:            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java:3027:                top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible);
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java:3465:                        r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java:1457:                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java:1877:            app.thread.scheduleCreateService(r, r.serviceInfo,
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java:1985:                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java:2079:                        r.app.thread.scheduleUnbindService(r,
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java:2135:                    r.app.thread.scheduleStopService(r);
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java:2240:                    s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java:3436:                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java:269:        r.receiver = app.thread.asBinder();
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java:286:            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java:476:                    app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java:464:            app.thread.scheduleActivityConfigurationChanged(
frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java:477:            app.thread.scheduleMultiWindowModeChanged(appToken, !task.mFullscreen);
frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java:488:            app.thread.schedulePictureInPictureModeChanged(
frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java:962:                app.thread.scheduleNewIntent(
frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java:1322:                app.thread.scheduleSleeping(appToken, _sleeping);
frameworks/base/services/core/java/com/android/server/am/CompatModePackages.java:379:                        app.thread.updatePackageCompatibilityInfo(packageName, ci);
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:1160:                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:1935:                        r.app.thread.scheduleWindowVisibility(r.appToken, false);
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:1998:            r.app.thread.scheduleWindowVisibility(r.appToken, true);
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:2015:                r.app.thread.scheduleOnNewActivityOptions(r.appToken, r.returningOptions);
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:2065:                        waitingActivity.app.thread.scheduleTranslucentConversionComplete(
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:2536:                        next.app.thread.scheduleSendResult(next.appToken, a);
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:2553:                    next.app.thread.scheduleNewIntent(
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:2570:                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:3238:                r.app.thread.scheduleSendResult(r.appToken, list);
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:3344:                r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:3465:                            r.app.thread.scheduleLocalVoiceInteractionStarted((IBinder) r.appToken,
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:4072:                r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:4166:                    r.app.thread.scheduleCancelVisibleBehind(r.appToken);
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java:4821:            r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes,

2.3 AMS建立和Android應用程式以及關聯的四大組件之間的Binder通信小結

??至此AMS建立和Android應用程式以及關聯的四大組件之間的Binder通信就到這里就告一段落了,它最終是借助匿名Binder的代理端ATP完成了這一切!分析完結我們發現無論是AMS和應用程式通信還是應用程式和AMS之間的通信都是通過Binder的邏輯進行的,只不過一個是實名Binder通信一個是匿名Binder通信而已,所以Android原始碼的原始碼學習一定是繞不開Binder的,讀者一定要有所掌握不然真的很難深入理解Android原始碼的一些設計理念,




總結

??Android應用程式建立與AMS服務之間的通信程序到這里就要完結了,通過前面的介紹我們知道了Android應用程式和AMS之間的互動主要是通過IApplicationThread與IActivityManager這兩個介面來完成的,IActivityManager實作了Android應用程式到AMS之間通信,而IApplicationThread實作了AMS到Android應用程式之間的通信,但是我們這里發現了無論是借助于那個介面,最終都脫離不了Binder通信,所以所以Android原始碼的原始碼學習一定是繞不開Binder的,讀者一定要有所掌握不然真的很難深入理解Android原始碼的一些設計理念(打個廣告,可以看看我的系列博客Android Binder框架學習系列博客),好了,青山不改綠水長流先到這里了,如果本博客對你有所幫助,麻煩關注或者點個贊,如果覺得很爛也可以踩一腳!謝謝各位了!!

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/232123.html

標籤:其他

上一篇:React-Native + 極光推送

下一篇:iOS開發之轉盤選單—Swift

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more