之前的文章中最Messenager做过简单的介绍,但是在进程间的通讯实例却一直没有搞出来。下面演示简单的事例:
需求是这样的:我们需要具体的功能《垃圾清理》,既可以在App中调用,也可以在系统中快捷调用,同时可以不依赖于系统独立的运行与App中,App可以独立安装。而且这个功能比较耗时,调用端只关心是否成功,以及完成之后的结果状态。
经过分析,由于操作比较耗时,而且要刻意跨进程调用,因此必须采用服务的形式来解决问题。看代码:
AndroidMainifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.gzgd.focustest" android:sharedUserId="android.uid.system" coreApp="true"> <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" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".TostService" android:enabled="true" android:exported="true"></service> </application> </manifest>
service 的代码:
tostservice.java
package com.gzgd.focustest; import android.annotation.SuppressLint; import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; import android.widget.Toast; public class TostService extends Service { public static String TAG ="yan"; @SuppressLint("HandlerLeak") public Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { switch(msg.what){ case 1: Messenger callBack =msg.replyTo; show(); Log.i(TAG,"eeEEEEEEEEEEEEEEEEEEEEEEEEE"); Message reply=Message.obtain(null,1); try { callBack.send(reply); } catch (RemoteException e) { e.printStackTrace(); } } } }; public void show(){ Toast ts=Toast.makeText(this,"Just a test!!! Tostservice",Toast.LENGTH_LONG); //ts.setText("Just a test!!! Tostservice "); ts.setDuration(Toast.LENGTH_LONG); ts.show(); } public TostService() { } @Override public void onCreate() { super.onCreate(); } @Override public IBinder onBind(Intent intent) { return new Messenger(mHandler).getBinder(); } }
在App本身的应用中的代码:
package com.gzgd.focustest; import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.annotation.NonNull; import android.support.design.widget.BottomNavigationView; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.TextView; import java.security.PrivateKey; public class MainActivity extends AppCompatActivity { private String TAG = "keyan"; private TextView mTextMessage; public Button bt; public Button bt2; private Messenger mscl; @SuppressLint("HandlerLeak") private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: Log.d(TAG, "yes????"); } } }; private Messenger mServiceMessager; private Messenger mClientMeassager; ServiceConnection mTostserviceconnection =new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mServiceMessager=new Messenger(service); } @Override public void onServiceDisconnected(ComponentName name) { mServiceMessager=null; } }; public void binMessagerservice(){ Intent intent = new Intent(this, TostService.class); bindService(intent,mTostserviceconnection,BIND_AUTO_CREATE); } public void sendMessage(){ Message ms = Message.obtain(null,1); ms.replyTo= mClientMeassager; try { mServiceMessager.send(ms); } catch (RemoteException e) { e.printStackTrace(); } } private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.navigation_home: mTextMessage.setText(R.string.title_home); return true; case R.id.navigation_dashboard: mTextMessage.setText(R.string.title_dashboard); return true; case R.id.navigation_notifications: mTextMessage.setText(R.string.title_notifications); return true; } return false; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mClientMeassager=new Messenger(mHandler); binMessagerservice(); mTextMessage = (TextView) findViewById(R.id.message); bt =(Button)findViewById(R.id.button); bt2 =(Button)findViewById(R.id.button2); bt.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if(hasFocus){ v.setScaleX((float) 1.2); v.setScaleY((float) 1.2); v.setTranslationX((float) 1.8); v.setAlpha((float)0.2); bt.animate().setDuration(50000); }else { v.setScaleX(1); v.setScaleY(1); v.setAlpha(1); } } }); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //binMessagerservice(); Log.i(TAG,"sendMessage>>>>>>>>>>>>>>>>>>>>>>>>>>"); sendMessage(); Log.i(TAG,"sendMessage>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<"); } }); bt2.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if(hasFocus){ v.setScaleX(2); v.setScaleY(2); bt2.animate().setDuration(300); }else { v.setScaleX(1); v.setScaleY(1); } } }); BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation); navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); } }
在系统中,增加的代码:
final Object mSystemcleanLock = new Object();
ServiceConnection mSystemcleanConnection = null;
final Runnable mSystemcleanTimeout = new Runnable() {
@Override public void run() {
synchronized (mSystemcleanLock) {
if (mSystemcleanConnection != null) {
mContext.unbindService(mSystemcleanConnection);
mSystemcleanConnection = null;
}
}
}
};
// Assume this is called from the Handler thread.
private void takeSystemclean() {
Log.i(TAG,"takesystemclean >>>>>>>>>>>>>>>>>>>");
synchronized (mSystemcleanLock) {
if (mSystemcleanConnection != null) {
return;
}
ComponentName cn = new ComponentName("com.gzgd.focustest",
"com.gzgd.focustest.TostService");
Intent intent = new Intent();
intent.setComponent(cn);
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (mSystemcleanLock) {
if (mSystemcleanConnection != this) {
Log.i(TAG,"zhe gehentdan 00001");
return;
}
Messenger messenger = new Messenger(service);
Message msg = Message.obtain(null, 1);
final ServiceConnection myConn = this;
Handler h = new Handler(mHandler.getLooper()) {
@Override
public void handleMessage(Message msg) {
synchronized (mSystemcleanLock) {
if (mSystemcleanConnection == myConn) {
mContext.unbindService(mSystemcleanConnection);
mSystemcleanConnection = null;
mHandler.removeCallbacks(mSystemcleanTimeout);
}
}
}
};
msg.replyTo = new Messenger(h);
msg.arg1 = msg.arg2 = 0;
msg.arg1 = 1;
msg.arg2 = 1;
try {
messenger.send(msg);
} catch (RemoteException e) {
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {}
};
if (mContext.bindServiceAsUser(
intent, conn, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {
mSystemcleanConnection = conn;
mHandler.postDelayed(mSystemcleanTimeout, 10000);
}
}
}
最后的效果是,apk可以独立于系统快捷,安装在任何系统中,也可以在系统中增加快捷调用代码。