当前位置: 移动技术网 > 移动技术>移动开发>Android > Android通过RemoteViews实现跨进程更新UI示例

Android通过RemoteViews实现跨进程更新UI示例

2019年07月24日  | 移动技术网移动技术  | 我要评论

一、概述

前面一篇文章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.aidl
package 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,0,intentclick,0);
    remoteviews.setonclickpendingintent(r.id.firstbutton,openfirstactivity);

    intent secondclick = new intent(temp2activity.this,secondactivity.class);
    pendingintent opensecondactivity = pendingintent.getactivity(temp2activity.this,0,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还得看实际的需求。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网