13. VirtualApk 원리 요약
플러그인을 초기화할 때 VirtualApk는 모든 플러그인의 모든 정보를 하나의 LoadedPlugin 대상에 해석합니다. 위에서 언급한 ClassLoader와 Resources, 4대 구성 요소 정보, 패키지 관련 정보 등을 포함합니다. 이 과정은 시스템이 숙주 apk의 해석 방식을 분석하고 이 LoadedPlugin을 가져와서 준비할 수 있습니다.
Activity
VirtualApk은 어떻게 플러그인의 activity를 시작합니까?간단하게 말하면 구덩이를 차지하는activity를 미리 설정하여 플러그인activity를 시작할 때 구덩이activity를 시작하여 AMS 검사를 돌고 마지막으로 플러그인activity를 다시 교체하여 시작하는 목적을 달성한다.실현 방식은 훅시스템의 Instrumentation을 통해execStartActivity 방법에 플러그인 정보를 저장하고 적당한 점거activity를 찾아 새로운 Intent를 구축하고 AMS 검사를 돌아서 Instrumentation이 newActivity를 통과할 때 목표의Activity를 바꾸어 플러그인Activity를 시작하는 목적을 달성하는 것이다.이 과정에서 플러그인 ClassLoader와 플러그인 Resource가 결정적인 역할을 했습니다.
Receiver
Receiver의 구현은 비교적 간단합니다. 플러그인을 불러올 때 안드로이드 매니페스트에 정적 등록된 모든 Receiver를 읽고 동적 등록을 합니다.
// Register broadcast receivers dynamically
Map receivers = new HashMap();
for (PackageParser.Activity receiver : this.mPackage.receivers) {
receivers.put(receiver.getComponentName(), receiver.info);
BroadcastReceiver br = BroadcastReceiver.class.cast(getClassLoader().loadClass(receiver.getComponentName().getClassName()).newInstance());
for (PackageParser.ActivityIntentInfo aii : receiver.intents) {
this.mHostContext.registerReceiver(br, aii);
}
}
Service
서비스 플러그인화는 여러 가지 Activity 형식에 구덩이를 뚫는 것과 같은 방식이 아니라 로컬에서 Local Service를 정의했다. hook Inactivity Manager를 통해 서비스를 시작하거나 끄는 방법을 차단한다. 예를 들어 start Service stop Service bind Service unBind Service 등은 이 local Service를 시작한 다음에 Local Service에서 나누어 주고 전송된 데이터에 따라 시작할 대상 서비스를 확정한다.그리고 플러그인 클래스 로더를 통해 플러그인에서 이 클래스를 불러오고 창설 대상을 반사합니다. 서비스의attach 방법을 반사하여 우리가 연결한 파라미터를 전송하고 서비스 대상의 onCreate를 실행하면 됩니다. 다른 작업은 마찬가지입니다.
switch (command) {
case EXTRA_COMMAND_START_SERVICE: {
......
service = (Service) plugin.getClassLoader().loadClass(component.getClassName()).newInstance();
Application app = plugin.getApplication();
IBinder token = appThread.asBinder();
Method attach = service.getClass().getMethod("attach", Context.class, ActivityThread.class, String.class, IBinder.class, Application.class, Object.class);
IActivityManager am = mPluginManager.getActivityManager();
attach.invoke(service, plugin.getPluginContext(), mainThread, component.getClassName(), token, app, am);
service.onCreate();
......
break;
}
case EXTRA_COMMAND_BIND_SERVICE: {
......
break;
}
case EXTRA_COMMAND_STOP_SERVICE: {
......
break;
}
case EXTRA_COMMAND_UNBIND_SERVICE: {
......
break;
}
}
ContentProvider
Virtual Apk에서 Content Provider의 플러그인화도 프록시 전송 형식으로 이루어진 것이다. 외부에서 플러그인을 호출하는 Content Provider와 플러그인 내부에서 플러그인 자체를 호출하는 Content Provider 두 가지로 나뉘는데 두 번째 상황은 플러그인 내부에서 get Content Resolver가 Plugin Context를 통해 호출되는 것이다. 두 가지 원리는 같고 여기서 첫 번째 상황을 예로 들어 설명한다.플러그인 외부에서 플러그인 Content Provider를 이동하려면 Plugin Content Resolver를 통과해야 합니다.wrapperUri는 ui를 포장한 다음 getContent Resolver ().자리를 차지하는 Remote Content Provider가 그query 방법을 실행하도록 조정합니다. 이 방법에서 우리가 시작해야 할 Content Provider를 찾을 수 있습니다. 창설 대상을 찾은 후 반사하고, Content Provider의attach Info 방법으로 매개 변수를 연결하고, 이 Content Provider의query 방법을 호출하여 조회합니다. 다른 방법은 같은 이치입니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.