加快连接管理服务的速度

This commit is contained in:
keyongyu
2017-08-04 11:19:29 +08:00
parent 575afbc595
commit bec29ffaf1
7 changed files with 245 additions and 6 deletions
@@ -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) {
}
}
}
}
+1 -1
View File
@@ -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