日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android中Intent连接不同组件的原理

發布時間:2025/3/15 Android 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android中Intent连接不同组件的原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、什么是Intent

1、概念

Intent翻譯過來是”意圖、目的”的意思,是連接四大組件的橋梁,作為中介傳輸信息.

2、類型

Intent分為兩種,顯示和隱示.顯示需要指定目標組件信息,隱示則只需要指定被目標組件響應的信息(action和category等信息).

3、屬性

component(組件):目的組件?
action(動作):用來表現意圖的行動?
category(類別):用來表現動作的類別?
data(數據):表示與動作要操縱的數據?
type(數據類型):對于data范例的描寫?
extras(擴展信息):擴展信息?
Flags(標志位):期望這個意圖的運行模式?
.?
二、連接不同組件的原理

這里以Activity里啟動Service為例,來分析原理.

Intent intent = new Intent(MainActivity.this, MainService.class); startService(intent);
  • 1

1、點擊跳轉到Intent帶有這兩個參數的構造方法

public class Intent implements Parcelable, Cloneable {...... public Intent(Context packageContext, Class<?> cls) {mComponent = new ComponentName(packageContext, cls);} ...... }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在這里只是新建了ComponentName實例.

2、好,回到startService(intent),點擊會跳轉到ContextWrapper類

public class ContextWrapper extends Context {Context mBase; ...... @Override public ComponentName startService(Intent service) { return mBase.startService(service); } ...... }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3、在這個方法里調用mBase的startService方法,這個mBase其實是ContextIml的實例,ContextIml也繼承自Context,代碼位于/frameworks/base/core/java/android/app/ContextImpl.java。?
這里順便介紹下Context、ContextWrapper 、ContextImpl的關系.直接?
放圖吧。

?

4、好,繼續看ContextImpl類中的startService實現.?
PS:給大家推薦一個在線看源碼的網站?點擊打開

class ContextImpl extends Context { ...... @Override public ComponentName startService(Intent service) {try {service.setAllowFds(false); ComponentName cn=ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver())); if (cn != null && cn.getPackageName().equals()) { throw new SecurityException( + service + + cn.getClassName()); } return cn; } catch (RemoteException e) {return null; } } ...... }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

5、在這里調用了ActivityManagerNative的getDefault方法返回的是gDefault.get()方法.

public abstract class ActivityManagerNative extends Binder implements IActivityManager {...... static public IActivityManager getDefault() {return gDefault.get(); } ......}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6、gDefault.get()方法返回的是IActivityManager對象.IActivityManager是一個Binder對象.

{ ...... private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {protected IActivityManager create() {IBinder b = ServiceManager.getService();if (false) {Log.v(, + b); } IActivityManager am = asInterface(b); if (false) {Log.v(, + am); } return am; } }; ...... }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

7、回到第4步.

ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()));
  • 1

調用了IActivityManager的startService方法,IActivityManager是一個抽象類,由它的實現類ActivityManagerProxy來實現.

8、看下它的實現

class ActivityManagerProxy implements IActivityManager { ...... public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); service.writeToParcel(data, 0); data.writeString(resolvedType); mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0); reply.readException(); ComponentName res = ComponentName.readFromParcel(reply); data.recycle(); reply.recycle(); return res; } ...... }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

startService傳入是三個參數:IApplicationThread 、Intent 、resolvedType.

第一個參數IApplicationThread是一個接口, 由主進程ActivityThread創建的一個Binder對象.第二個參數Intent 不用說了第三個參數是Intent 的MIME類型

9、接下來關鍵的一行代碼

mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
  • 1

這個transact方法會進入Binder驅動程序.Binder驅動程序喚醒正在等待的ActivityManagerService進程,最后進入到ActivityManagerService的startService函數中。

public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {{ ...... public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType) {// Refuse possible leaked file descriptors if (service != null && service.hasFileDescriptors() == true) {throw new IllegalArgumentException(); } synchronized(this) {final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res = startServiceLocked(caller, service, resolvedType, callingPid, callingUid); Binder.restoreCallingIdentity(origId); return res; } } ...... }}}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

10、從Binder里獲取到pid和uid,添加這兩個參數到startServiceLocked方法.

public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {{ ...... ComponentName startServiceLocked(IApplicationThread caller,Intent service, String resolvedType,int callingPid, int callingUid) { ...... ServiceLookupResult res =retrieveServiceLocked(service, resolvedType,callingPid, callingUid); ServiceRecord r = res.record; ...... return r.name; } ...... }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

11、在這個方法里,調用retrieveServiceLocked方法解析service這個Intent.至此,Intent的使命基本結束了,我就不繼續追蹤服務的啟動了.大家感興趣可以自己往下跟蹤.

三、總結

Intent是作為一個參數,攜帶相關的信息.

1、由主進程通過Binder進入AMS進程?
2、 在AMS進程獲取和管理要啟動的服務的相關信息?
3、 由AMS進程回到該主進程啟動服務

而Intent一直是貫穿始終的.

最后附上從網上找到的整個流程圖,,幫大家理

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的Android中Intent连接不同组件的原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。