一、概述
前面一篇文章AndroID通过AIDL实现跨进程更新UI我们学习了aIDl跨进程更新ui,这种传统方式实现跨进程更新UI是可行的,但有以下弊端:
VIEw中的方法数比较多,在IPC中需要增加对应的方法比较繁琐。 VIEw的每一个方法都会涉及到IPC *** 作,多次IPC带来的开销问题不容小觑。 VIEw中方法的某些参数可能不支持IPC传输。例如:OnClickListener,它仅仅是个接口没有序列化。接下来我们通过RemoteVIEws实现跨进程更新UI
二、实现效果图
在同一个应用中有两个Activity,MainActivity和Temp2Activity,这两个Activity不在同一个进程中。
现在需要通过Temp2Activity来改变MainActivity中的视图,即在MainActivity中添加两个button,也就是实现跨进程更新UI这么一个功能。
在MainActivity里点击“跳转到新进程ACTIVITY”按钮,会启动一个新进程的Temp2Activity,我们先点击“绑定服务”,这样我们就启动了服务,再点击“AIDL更新”按钮,通过调用handler来实现跨进程更新UI,点击返回,我们发现MainActivity页面中新添加了两个按钮,并且按钮还具有点击事件。
三、核心代码
IremoteVIEwsManager.aIDl
里面提供了两个方法,一个是根据ID更新TextVIEw里面的内容,一个是根据ID添加vIEw视图
// IremoteVIEwsManager.aIDl.aIDlpackage com.czhappy.remotevIEwdemo;interface IremoteVIEwsManager { voID addRemoteVIEw(in RemoteVIEws remoteVIEws);}
RemoteVIEwsAIDLService.Java
package com.czhappy.remotevIEwdemo.service;import androID.app.Service;import androID.content.Intent;import androID.os.Binder;import androID.os.Bundle;import androID.os.IBinder;import androID.os.Message;import androID.os.remoteexception;import androID.Widget.RemoteVIEws;import com.czhappy.remotevIEwdemo.IremoteVIEwsManager;import com.czhappy.remotevIEwdemo.activity.MainActivity;/** * Description: * User: chenzheng * Date: 2017/2/10 0010 * Time: 10:56 */public class RemoteVIEwsAIDLService extends Service { private static final String TAG = "RemoteVIEwsAIDLService"; private Binder remoteVIEwsBinder = new IremoteVIEwsManager.Stub(){ @OverrIDe public voID addRemoteVIEw(RemoteVIEws remoteVIEws) throws remoteexception { Message message = new Message(); message.what = 1; Bundle bundle = new Bundle(); bundle.putParcelable("remoteVIEws",remoteVIEws); message.setData(bundle); new MainActivity.MyHandler(RemoteVIEwsAIDLService.this,getMainLooper()).sendMessage(message); } }; public RemoteVIEwsAIDLService() { } @OverrIDe public IBinder onBind(Intent intent) { return remoteVIEwsBinder; }}
MainActivity.java
package com.czhappy.remotevIEwdemo.activity;import androID.content.Context;import androID.content.Intent;import androID.os.Bundle;import androID.os.Handler;import androID.os.Looper;import androID.os.Message;import androID.support.v7.app.AppCompatActivity;import androID.util.Log;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.Widget.linearLayout;import androID.Widget.RemoteVIEws;import androID.Widget.TextVIEw;import com.czhappy.remotevIEwdemo.R;import java.lang.ref.WeakReference;public class MainActivity extends AppCompatActivity { private static String TAG = "MainActivity"; private static linearLayout mlinearLayout; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); mlinearLayout = (linearLayout) this.findVIEwByID(R.ID.mylayout); } public static class MyHandler extends Handler { WeakReference<Context> weakReference; public MyHandler(Context context,Looper looper) { super(looper); weakReference = new WeakReference<>(context); } @OverrIDe public voID handleMessage(Message msg) { super.handleMessage(msg); Log.i(TAG,"handleMessage"); switch (msg.what) { case 1: //RemoteVIEws的AIDL实现 RemoteVIEws remoteVIEws = msg.getData().getParcelable("remoteVIEws"); if (remoteVIEws != null) { Log.i(TAG,"updateUI"); VIEw vIEw = remoteVIEws.apply(weakReference.get(),mlinearLayout); mlinearLayout.addVIEw(vIEw); } break; default: break; } } }; public voID readyGo(VIEw vIEw){ Intent intent = new Intent(MainActivity.this,Temp2Activity.class); startActivity(intent); }}
Temp2Activity.java
package com.czhappy.remotevIEwdemo.activity;import androID.app.PendingIntent;import androID.content.Componentname;import androID.content.Context;import androID.content.Intent;import androID.content.ServiceConnection;import androID.os.Bundle;import androID.os.IBinder;import androID.os.remoteexception;import androID.support.annotation.Nullable;import androID.support.v7.app.AppCompatActivity;import androID.util.Log;import androID.vIEw.VIEw;import androID.Widget.RemoteVIEws;import com.czhappy.remotevIEwdemo.IremoteVIEwsManager;import com.czhappy.remotevIEwdemo.R;import com.czhappy.remotevIEwdemo.service.RemoteVIEwsAIDLService;/** * Description: * User: chenzheng * Date: 2017/2/9 0009 * Time: 16:05 */public class Temp2Activity extends AppCompatActivity { private String TAG = "Temp2Activity"; private IremoteVIEwsManager remoteVIEwsManager; private boolean isBind = false; private ServiceConnection remoteVIEwServiceConnection = new ServiceConnection() { @OverrIDe public voID onServiceConnected(Componentname name,IBinder service) { Log.i(TAG,"onServiceConnected"); remoteVIEwsManager = IremoteVIEwsManager.Stub.asInterface(service); } @OverrIDe public voID onServicedisconnected(Componentname name) { //回收 remoteVIEwsManager = null; } }; @OverrIDe protected voID onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentVIEw(R.layout.activity_temp); } /** * 绑定服务 */ public voID bindService(VIEw vIEw) { Intent vIEwServiceIntent = new Intent(this,RemoteVIEwsAIDLService.class); isBind = bindService(vIEwServiceIntent,remoteVIEwServiceConnection,Context.BIND_auto_CREATE); } /** * 更新UI */ public voID UpdateUI(VIEw vIEw){ RemoteVIEws remoteVIEws = new RemoteVIEws(Temp2Activity.this.getPackagename(),R.layout.button_layout); Intent intentClick = new Intent(Temp2Activity.this,FirstActivity.class); PendingIntent openFirstActivity = PendingIntent.getActivity(Temp2Activity.this,intentClick,0); remoteVIEws.setonClickPendingIntent(R.ID.firstbutton,openFirstActivity); Intent secondClick = new Intent(Temp2Activity.this,SecondActivity.class); PendingIntent openSecondActivity = PendingIntent.getActivity(Temp2Activity.this,secondClick,0); remoteVIEws.setonClickPendingIntent(R.ID.secondbutton,openSecondActivity); remoteVIEws.setCharSequence(R.ID.secondbutton,"setText","想改就改"); try { remoteVIEwsManager.addRemoteVIEw(remoteVIEws); } catch (remoteexception e) { e.printstacktrace(); } } @OverrIDe protected voID onDestroy() { super.onDestroy(); if(isBind){ unbindService(remoteVIEwServiceConnection); isBind = false; } }}
AndroIDManifest.xml
<?xml version="1.0" enCoding="utf-8"?><manifest xmlns:androID="http://schemas.androID.com/apk/res/androID" package="com.czhappy.remotevIEwdemo"> <application androID:allowBackup="true" androID:icon="@mipmap/ic_launcher" androID:label="@string/app_name" androID:supportsRtl="true" androID:theme="@style/Apptheme"> <activity androID:name=".activity.MainActivity"> <intent-filter> <action androID:name="androID.intent.action.MAIN" /> <category androID:name="androID.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity androID:name=".activity.FirstActivity" /> <activity androID:name=".activity.SecondActivity" /> <activity androID:name=".activity.Temp2Activity" androID:process=":remote2" /> <service androID:name="com.czhappy.remotevIEwdemo.service.RemoteVIEwsAIDLService" /> </application></manifest>
四、总结
RemoteVIEws就是为跨进程更新UI而生的,内部封装了很多方法用来实现跨进程更新UI。但这并不代表RemoteVIEws是就是万能的了,它也有不足之处,目前支持的布局和VIEw有限
layout:
FrameLayout linearLayout relativeLayout GrIDLayout
VIEw:
AnalogClock button Chronometer Imagebutton ImageVIEw Progressbar TextVIEw VIEwFlipper ListVIEw GrIDVIEw StackVIEw AdapterVIEwFlipper VIEwStub
不支持自定义view 所以具体使用RemoteVIEws还是aIDl或者broadCastReceiver还得看实际的需求。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android通过RemoteViews实现跨进程更新UI示例全部内容,希望文章能够帮你解决Android通过RemoteViews实现跨进程更新UI示例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)