一. bean
RequestBean
public class RequestBean {
private String className;
private String methodName;
private int type;
private RequestParamter[] requestParamters;
public RequestBean() {
}
public RequestBean(int type, String className, String methodName, RequestParamter[] requestParamters) {
this.type = type;
this.className = className;
this.methodName = methodName;
this.requestParamters = requestParamters;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public RequestParamter[] getRequestParamters() {
return requestParamters;
}
public void setRequestParamters(RequestParamter[] requestParamters) {
this.requestParamters = requestParamters;
}
}
RequestParamter
public class RequestParamter {
private String parameterClassName;
private String parameterValue;
public RequestParamter() {
}
public RequestParamter(String parameterClassName, String parameterValue) {
this.parameterClassName = parameterClassName;
this.parameterValue = parameterValue;
}
public String getParameterClassName() {
return parameterClassName;
}
public void setParameterClassName(String parameterClassName) {
this.parameterClassName = parameterClassName;
}
public String getParameterValue() {
return parameterValue;
}
public void setParameterValue(String parameterValue) {
this.parameterValue = parameterValue;
}
}
二. CacheCenter
public class CacheCenter {
private ConcurrentHashMap<String, Class<?>> mClassMap;
private ConcurrentHashMap<String, ConcurrentHashMap<String, Method>> mAllMethodMap;
private ConcurrentHashMap<String, Object> mInstanceObjectMap;
private static final CacheCenter ourInstance = new CacheCenter();
public static CacheCenter getInstance() {
return ourInstance;
}
public void putObject(String className, Object instance) {
mInstanceObjectMap.put(className, instance);
}
public Object getObject(String className) {
return mInstanceObjectMap.get(className);
}
private CacheCenter() {
mClassMap = new ConcurrentHashMap<String, Class<?>>();
mAllMethodMap = new ConcurrentHashMap<String, ConcurrentHashMap<String, Method>>();
mInstanceObjectMap = new ConcurrentHashMap<String, Object>();
}
public void register(Class clazz) {
registerClass(clazz);
registerMethod(clazz);
}
private void registerClass(Class clazz) {
String className = clazz.getName();
mClassMap.put(className, clazz);
}
public Method getMethod(RequestBean requestBean) {
ConcurrentHashMap<String, Method> map = mAllMethodMap.get(requestBean.getClassName());
if (map != null) {
String key = getMethodParameters(requestBean);
return map.get(key);
}
return null;
}
public Class<?> getClassType(String parameterClassName) {
try {
Class clazz = Class.forName(parameterClassName);
return clazz;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
private void registerMethod(Class clazz) {
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
ConcurrentHashMap<String, Method> map = mAllMethodMap.get(clazz.getName());
if (map == null) {
map = new ConcurrentHashMap<String, Method>();
mAllMethodMap.put(clazz.getName(),map);
}
String key = getMethodParameters(method);
map.put(key, method);
}
}
public static String getMethodParameters(Method method) {
StringBuilder result = new StringBuilder();
result.append(method.getName());
Class<?>[] classes=method.getParameterTypes();
int length = classes.length;
if (length == 0) {
return result.toString();
}
for (int i = 0; i < length; ++i) {
result.append("-").append(classes[i].getName());
}
return result.toString();
}
public static String getMethodParameters(RequestBean requestBean) {
StringBuilder result = new StringBuilder();
result.append(requestBean.getMethodName());
if (requestBean.getRequestParamters() == null || requestBean.getRequestParamters().length == 0) {
return result.toString();
}
int length = requestBean.getRequestParamters().length;
RequestParamter[] requestParamters=requestBean.getRequestParamters();
for (int i = 0; i < length; ++i) {
result.append("-").append(requestParamters[i].getParameterClassName());
}
return result.toString();
}
}
三. core
BinderIPC
public class BinderIPC {
private CacheCenter cacheCenter = CacheCenter.getInstance();
private static final BinderIPC ourInstance = new BinderIPC();
BinderInterface binderInterface;
private static final Gson GSON = new Gson();
private Context sContext;
public static BinderIPC getDefault() {
return ourInstance;
}
public void init(Context context) {
sContext = context.getApplicationContext();
}
public void register(Class<?> clazz) {
cacheCenter.register(clazz);
}
public <T> T getInstance(Class<T> clazz, Object... parameters) {
sendRequest(clazz, null, parameters, ServiceManager.TYPE_GET);
return getProxy(clazz);
}
private <T> T getProxy(Class<T> clazz) {
ClassLoader classLoader = sContext.getClassLoader();
return (T) Proxy.newProxyInstance(classLoader, new Class[]{clazz}, new BinderProxy(clazz));
}
public <T> String sendRequest(Class<T> clazz, Method method, Object[] parameters, int type) {
String className = clazz.getAnnotation(ClassId.class).value();
String methodName = method == null ? "getInstance" : method.getName();
RequestParamter[] requestParamters = null;
if (parameters != null && parameters.length >0) {
requestParamters = new RequestParamter[parameters.length];
for (int i = 0; i < parameters.length; i++) {
Object parameter = parameters[i];
String parameterClassName = parameter.getClass().getName();
String parameterValue = GSON.toJson(parameter);
RequestParamter requestParamter = new RequestParamter(parameterClassName, parameterValue);
requestParamters[i] = requestParamter;
}
}
RequestBean requestBean = new RequestBean(type, className, methodName, requestParamters);
String request = GSON.toJson(requestBean);
String responce = null;
try {
responce= binderInterface.reuqest(request);
} catch (RemoteException e) {
e.printStackTrace();
}
return responce;
}
public void open(Context context) {
open(context, null);
}
public void open(Context context, String packageName) {
init(context);
bind(context.getApplicationContext(), packageName, ServiceManager.class);
}
private void bind(Context context, String packageName, Class<? extends ServiceManager> service) {
Intent intent = null;
if (TextUtils.isEmpty(packageName)) {
intent = new Intent(context, service);
}else {
ComponentName component = new ComponentName(packageName, service.getName());
intent = new Intent();
intent.setComponent(component);
intent.setAction(service.getName());
}
ServiceConnection serviceConnection = new IPCServiceConnection();
context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private class IPCServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binderInterface = BinderInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
BinderProxy
public class BinderProxy implements InvocationHandler {
private Class clazz;
private static final Gson GSON = new Gson();
public BinderProxy( Class clazz) {
this.clazz = clazz;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String data = BinderIPC.getDefault().sendRequest(clazz, method,
args, ServiceManager.TYPE_INVOKE);
if (!TextUtils.isEmpty(data)) {
Object object= GSON.fromJson(data, method.getReturnType());
return object;
}
return null;
}
}
四. 自定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassId {
String value();
}
一. 自定义Service
public class ServiceManager extends Service {
private Gson gson = new Gson();
//服务获取
public static final int TYPE_GET = 1;
//服务调用
public static final int TYPE_INVOKE = 2;
private CacheCenter cacheCenter = CacheCenter.getInstance();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new BinderInterface.Stub() {
@Override
public String reuqest(String reuqest) throws RemoteException {
RequestBean requestBean = gson.fromJson(reuqest, RequestBean.class);
int type = requestBean.getType();
switch (type) {
case TYPE_GET:
Method method = cacheCenter.getMethod(requestBean);
Object[] parameters = makeParameterObject(requestBean);
if (method != null) {
try {
Object object= method.invoke(null, parameters);
if (object != null) {
cacheCenter.putObject(requestBean.getClassName(), object);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
break;
case TYPE_INVOKE:
Object object = cacheCenter.getObject(requestBean.getClassName());
Method tempMethod = cacheCenter.getMethod(requestBean);
Object[] mParameters = makeParameterObject(requestBean);
try {
Object result=tempMethod.invoke(object, mParameters);
String data = gson.toJson(result);
return data;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
break;
}
return null;
}
};
}
private Object[] makeParameterObject(RequestBean requestBean) {
Object[] mParameters = null;
RequestParamter[] requestParamters = requestBean.getRequestParamters();
if (requestParamters != null && requestParamters.length > 0) {
mParameters = new Object[requestBean.getRequestParamters().length];
for (int i = 0; i < requestParamters.length; i++) {
RequestParamter requestParamter = requestParamters[i];
Class<?> clazz = cacheCenter.getClassType(requestParamter.getParameterClassName());
mParameters[i] = gson.fromJson(requestParamter.getParameterValue(), clazz);
}
}else {
mParameters = new Object[0];
}
return mParameters;
}
}
五. aidl文件
interface BinderInterface {
String reuqest(String reuqest);
}
六. 自定义主进程数据
public class UserInfo {
private String password;
private String name;
public UserInfo( ) {
}
public UserInfo(String password, String name) {
this.password = password;
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "UserInfo{" +
"password='" + password + '\'' +
", name='" + name + '\'' +
'}';
}
public void setName(String name) {
this.name = name;
}
}
@ClassId("com.luisliuyi.demo.binder.Singlton")
public interface ISinglton {
public UserInfo getUserInfo();
}
public class Singlton implements ISinglton{
private static Singlton sInstance = null;
private UserInfo userInfo;
private Singlton() {
}
public UserInfo getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo;
}
public static synchronized Singlton getInstance() {
if (sInstance == null) {
sInstance = new Singlton();
}
return sInstance;
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BinderIPC.getDefault().open(this);
//服务注册
BinderIPC.getDefault().register(Singlton.class);
Singlton.getInstance().setUserInfo(new UserInfo("123456","luis"));
}
public void change(View view) {
startActivity(new Intent(this, SecondActivity.class));
}
}
六. 自定义其他进程
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.luisliuyi.demo.binder">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity" android:process=":f"/>
<service android:name="com.luisliuyi.demo.binderlib.ServiceManager" android:exported="true">
<intent-filter>
<action android:name="com.example.ipclib.DavidServiceManager"></action>
</intent-filter>
</service>
</application>
</manifest>
public class SecondActivity extends Activity {
ISinglton service = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
BinderIPC.getDefault().open(this);
}
public void getService(View view) {
// 拿到接口 一定要 服务顾客
service = BinderIPC.getDefault().getInstance(ISinglton.class);
}
public void getUser(View view) {
Toast.makeText(this, service.getUserInfo().getName() + " : " + service.getUserInfo().getPassword(), Toast.LENGTH_SHORT).show();
}
}
七. 代码地址
https://gitee.com/luisliuyi/android-binder.git
网友评论