1.Apk動態解析載入流程原理分析? 第一步:主程式載入外掛程式 第二步:主程式啟動外掛流程分析 外掛程式實際上啟動的是代理物件,所以我們需要在清單檔案中配置代理物件的Activity 第三步:代理物件的執行流程
2.Service生命週期?
第一種:本地服務 第一點:應用程式內部使用
第二點:我們在應用程式中,直接通過startService啟動伺服器,通過stopService停止服務
第三點:我們可以通過Service內部呼叫stopSelf或者stopSelfResult()
複製程式碼
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
this.stopSelf();
return null;
}
}
複製程式碼
第四點:無論你呼叫多少次startService,當我們需要停止伺服器的時候,只需要呼叫一次(因為Service是單例)
第五點:生命週期
startService() -> onCreate() ->onStartCommand() -> Service Running -> stopService() ->onDestory();
第二種:遠端服務
第一點:用於Android系統內部應用程式直接的通訊(程式間的通訊)AIDL
第二點:需要定義介面(AIDL)暴露給外部,提供其他的應用進行訪問
第三點:客戶端建立Service,並且呼叫bindService(啟動Service)方法建立連線,斷開連線unBindService(關閉Service)
第四點:多個客戶端可以繫結同一個服務,如果這個服務沒有被建立,那麼就會呼叫bindService,如果已經建立了onStartCommand方法
第五點:生命週期
bindService->onCreate->onBind->Service Running->unBindService->onUnBind->onDestory
複製程式碼
3.Service外掛化架構設計實現? 3.1 角色劃分
3.2 功能實現
複製程式碼
使用 AIDL 跨應用通訊 服務端(Server)
public class TestService extends Service {
@Override
public ComponentName startService(Intent service) {
Log.i("main", "------startService------");
return super.startService(service);
}
@Override
public void onCreate() {
super.onCreate();
Log.i("main", "------onCreate------");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i("main", "------onStart------");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("main", "------onStartCommand------");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean stopService(Intent name) {
Log.i("main", "------stopService------");
return super.stopService(name);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new TestBind();
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("main", "------onDestroy------");
}
private class TestBind extends ITestServiceInterface.Stub{
@Override
public String getName() throws RemoteException {
//處理相關業務邏輯
return "我是A程式Service";
}
}
}
複製程式碼
AIDL 定義介面檔案ITestServiceInterface.aidl
interface ITestServiceInterface {
String getName();
}
複製程式碼
清單檔案中AndroidManifest.xml
<service
android:name="com.haocai.architect.plugin.remoteservice.a.TestService"
android:exported="true"
android:process=":remote">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="com.haocai.architect.plugin.remoteservice.a.TestService" />
</intent-filter>
</service>
複製程式碼
服務端包名(com.haocai.architect.plugin.remoteservice.a)
客戶端(Server)
public class MainActivity extends AppCompatActivity {
// 服務端包名(com.haocai.architect.plugin.remoteservice.a)
private static final String ACTION_TEST_SERVICE = "com.haocai.architect.plugin.remoteservice.a.TestService";
private Intent testIntent;
private ITestServiceInterface asInterface;
private TestConnection testConnection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testIntent = new Intent();
testConnection = new TestConnection();
}
public void startRemoteService(View v) {
//android 5.0以後直設定action不能啟動相應的服務,需要設定packageName或者Component。
testIntent.setAction(ACTION_TEST_SERVICE);
testIntent.setComponent(new ComponentName("com.haocai.architect.plugin.remoteservice.a", ACTION_TEST_SERVICE));
// testIntent.setPackage("com.haocai.architect.plugin.remoteservice.a");
testIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//繫結服務
bindService(testIntent, testConnection, Context.BIND_AUTO_CREATE);
}
public void stopRemoteService(View v) {
unbindService(testConnection);
}
@Override
protected void onDestroy() {
//解綁服務
if (asInterface != null) {
unbindService(testConnection);
}
super.onDestroy();
}
public void getName(View v) {
Log.d("main name","NULL");
if (asInterface != null) {
try {
String name = this.asInterface.getName();
Log.d("main name",name);
Toast.makeText(this, "name:" + name, Toast.LENGTH_SHORT).show();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
// 定義接收器(建立連結)
private class TestConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//通過服務端onBind方法返回的binder物件得到IMyService的例項,得到例項就可以呼叫它的方法了
asInterface = ITestServiceInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
asInterface= null;
}
}
}
複製程式碼
目標介面:IPluginService 目標物件:PluginService(外掛Service基類) 代理物件:ProxyPluginService
3.2功能實現 第一步:定義目標介面 - IPluginService 第二步:定義目標物件 - PluginService 第三步:定義代理物件 - ProxyPluginService 第四步:實現目標物件具體的細節 第五步:實現代理物件具體的細節 - ProxyPluginService 第六步:在PluginManager類中新增啟動服務的方法 第七步: