mirror of
https://github.com/DroidPluginTeam/DroidPlugin.git
synced 2026-10-17 04:30:34 +08:00
加快连接管理服务的速度
This commit is contained in:
@@ -187,6 +187,10 @@
|
||||
android:name=".PluginManagerService"
|
||||
android:label="@string/service_name_plugin_manager_service" />
|
||||
|
||||
<provider
|
||||
android:name=".PluginServiceProvider"
|
||||
android:authorities="${applicationId}.plugin.servicemanager"/>
|
||||
|
||||
<activity
|
||||
android:name="com.morgoo.droidplugin.stub.ShortcutProxyActivity"
|
||||
android:exported="true"
|
||||
|
||||
@@ -24,11 +24,13 @@ package com.morgoo.droidplugin;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
import com.morgoo.droidplugin.hook.handle.IActivityManagerHookHandle;
|
||||
import com.morgoo.droidplugin.pm.IPluginManagerImpl;
|
||||
import com.morgoo.droidplugin.pm.PluginManager;
|
||||
|
||||
/**
|
||||
* 插件管理服务。
|
||||
@@ -38,15 +40,25 @@ import com.morgoo.droidplugin.pm.IPluginManagerImpl;
|
||||
public class PluginManagerService extends Service {
|
||||
|
||||
private static final String TAG = PluginManagerService.class.getSimpleName();
|
||||
private IPluginManagerImpl mPluginPackageManager;
|
||||
private static IPluginManagerImpl mPluginPackageManager;
|
||||
|
||||
public static IPluginManagerImpl getPluginPackageManager(Context context) {
|
||||
if (mPluginPackageManager == null) {
|
||||
synchronized (PluginManager.class) {
|
||||
if (mPluginPackageManager == null) {
|
||||
mPluginPackageManager = new IPluginManagerImpl(context);
|
||||
mPluginPackageManager.onCreate();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mPluginPackageManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
keepAlive();
|
||||
mPluginPackageManager = new IPluginManagerImpl(this);
|
||||
mPluginPackageManager.onCreate();
|
||||
|
||||
getPluginPackageManager(this);
|
||||
}
|
||||
|
||||
private void keepAlive() {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.morgoo.droidplugin;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.morgoo.helper.compat.BundleCompat;
|
||||
|
||||
|
||||
public class PluginServiceProvider extends ContentProvider {
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri uri) {
|
||||
return uri.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues values) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle call(String method, String arg, Bundle extras) {
|
||||
if (Method_GetManager.equals(method)) {
|
||||
Uri uri = null;
|
||||
if (extras != null && extras.containsKey(URI_VALUE)) {
|
||||
uri = Uri.parse(extras.getString(URI_VALUE));
|
||||
}
|
||||
Bundle bundle = new Bundle();
|
||||
BundleCompat.putBinder(bundle, Arg_Binder, PluginManagerService.getPluginPackageManager(getContext()));
|
||||
return bundle;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static final String Method_GetManager = "getPluginManager";
|
||||
public static final String Arg_Binder = "_binder_";
|
||||
public static final String URI_KEY = "key";
|
||||
public static final String URI_VALUE = "uri";
|
||||
}
|
||||
@@ -38,6 +38,7 @@ import android.content.pm.PermissionInfo;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -45,8 +46,11 @@ import android.text.TextUtils;
|
||||
|
||||
import com.morgoo.droidplugin.BuildConfig;
|
||||
import com.morgoo.droidplugin.PluginManagerService;
|
||||
import com.morgoo.droidplugin.PluginServiceProvider;
|
||||
import com.morgoo.droidplugin.reflect.MethodUtils;
|
||||
import com.morgoo.helper.Log;
|
||||
import com.morgoo.helper.compat.BundleCompat;
|
||||
import com.morgoo.helper.compat.ContentProviderCompat;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
@@ -210,10 +214,24 @@ public class PluginManager implements ServiceConnection {
|
||||
Intent intent = new Intent(mHostContext, PluginManagerService.class);
|
||||
intent.setPackage(mHostContext.getPackageName());
|
||||
mHostContext.startService(intent);
|
||||
mHostContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
|
||||
|
||||
String auth = mHostContext.getPackageName() + ".plugin.servicemanager";
|
||||
Uri uri = Uri.parse("content://" + auth);
|
||||
Bundle args = new Bundle();
|
||||
args.putString(PluginServiceProvider.URI_VALUE, "content://" + auth);
|
||||
Bundle res = ContentProviderCompat.call(mHostContext, uri,
|
||||
PluginServiceProvider.Method_GetManager,
|
||||
null, args);
|
||||
if (res != null) {
|
||||
IBinder clientBinder = BundleCompat.getBinder(res, PluginServiceProvider.Arg_Binder);
|
||||
onServiceConnected(intent.getComponent(), clientBinder);
|
||||
} else {
|
||||
mHostContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "connectToService", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.morgoo.helper.compat;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author Lody
|
||||
*/
|
||||
public class BundleCompat {
|
||||
static Method getIBinder, putIBinder;
|
||||
|
||||
static {
|
||||
if (Build.VERSION.SDK_INT < 18) {
|
||||
try {
|
||||
getIBinder = Bundle.class.getDeclaredMethod("getIBinder", String.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
//ignore
|
||||
}
|
||||
try {
|
||||
putIBinder = Bundle.class.getDeclaredMethod("getIBinder", String.class, IBinder.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IBinder getBinder(Bundle bundle, String key) {
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
return bundle.getBinder(key);
|
||||
} else {
|
||||
if(getIBinder != null) {
|
||||
try {
|
||||
return (IBinder) getIBinder.invoke(bundle, key);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void putBinder(Bundle bundle, String key, IBinder value) {
|
||||
if (Build.VERSION.SDK_INT >= 18) {
|
||||
bundle.putBinder(key, value);
|
||||
} else {
|
||||
if(putIBinder != null) {
|
||||
try {
|
||||
putIBinder.invoke(bundle, key, value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.morgoo.helper.compat;
|
||||
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
|
||||
/**
|
||||
* @author Lody
|
||||
*/
|
||||
public class ContentProviderCompat {
|
||||
|
||||
public static Bundle call(Context context, Uri uri, String method, String arg, Bundle extras) {
|
||||
if (VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
return context.getContentResolver().call(uri, method, arg, extras);
|
||||
}
|
||||
ContentProviderClient client = crazyAcquireContentProvider(context, uri);
|
||||
Bundle res = null;
|
||||
try {
|
||||
res = client.call(method, arg, extras);
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
releaseQuietly(client);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private static ContentProviderClient acquireContentProviderClient(Context context, Uri uri) {
|
||||
if (VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
return context.getContentResolver().acquireUnstableContentProviderClient(uri);
|
||||
}
|
||||
return context.getContentResolver().acquireContentProviderClient(uri);
|
||||
}
|
||||
|
||||
public static ContentProviderClient crazyAcquireContentProvider(Context context, Uri uri) {
|
||||
ContentProviderClient client = acquireContentProviderClient(context, uri);
|
||||
if (client == null) {
|
||||
int retry = 0;
|
||||
while (retry < 5 && client == null) {
|
||||
SystemClock.sleep(100);
|
||||
retry++;
|
||||
client = acquireContentProviderClient(context, uri);
|
||||
}
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
public static ContentProviderClient crazyAcquireContentProvider(Context context, String name) {
|
||||
ContentProviderClient client = acquireContentProviderClient(context, name);
|
||||
if (client == null) {
|
||||
int retry = 0;
|
||||
while (retry < 5 && client == null) {
|
||||
SystemClock.sleep(100);
|
||||
retry++;
|
||||
client = acquireContentProviderClient(context, name);
|
||||
}
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
private static ContentProviderClient acquireContentProviderClient(Context context, String name) {
|
||||
if (VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
return context.getContentResolver().acquireUnstableContentProviderClient(name);
|
||||
}
|
||||
return context.getContentResolver().acquireContentProviderClient(name);
|
||||
}
|
||||
|
||||
public static void releaseQuietly(ContentProviderClient client) {
|
||||
if (client != null) {
|
||||
try {
|
||||
if (VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
client.close();
|
||||
} else {
|
||||
client.release();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
package="com.example.TestPlugin"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23"/>
|
||||
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="22"/>
|
||||
<application android:name="com.morgoo.droidplugin.PluginApplication" android:label="@string/app_name"
|
||||
android:icon="@drawable/ic_launcher" android:theme="@style/AppTheme">
|
||||
<activity
|
||||
|
||||
Reference in New Issue
Block a user