RemoteViews跨进程更新view

RemoteViews即远程view,这货能实现跨进程更新界面。

RemoteViews并不能支持所有的View类型,更不能自定义View。

  • layout
    • framelayout
    • linearlayout
    • relativelayout
    • gridlayout
  • view

    • analogclock
    • button
    • chronmeter
    • imagebutton
    • imageview
    • progressbar
    • textview
    • viewflipper
    • listview
    • gridview
    • stackview
    • adapterviewflipper
    • viewstub
  • 以上是RemoteViews支持的所有的view类型。

比如现在有两个应用,一个应用需要更新另一个应用的某个界面,这个时候我们当然可以选择AIDL去实现。但是对于界面更新比较频繁,这个时候就会有效率问题了,同时AIDL接口可能也会很复杂,这个时候采用RemoteViews来实现,就没有这个问题了。

以下以一个简单的例子来模拟通知栏和桌面小工具的底层实现原理。

  • 三下两除五直接上demo直接用轮子。

  • 简单的描述下实现的逻辑—Main3Activity作为更新ui的进程,先设置其在另外的进程,利用广播接收RemoteViews,然后收到Views后再更新view操作。所以发送广播的Main2Activity就是作为发送remoteviews的类,他所在的进程不同于Main3Activity,就实现了跨进程。

androidmainfest.xml

       ".Main2Activity"
            android:label="@string/title_activity_main2"
            android:theme="@style/AppTheme.NoActionBar" >

        

        ".Main3Activity"
            android:label="@string/title_activity_main3"
            android:process=":main3activity"
            android:theme="@style/AppTheme.NoActionBar">

            
                "android.intent.action.MAIN" />

                "android.intent.category.LAUNCHER" />
            



        
Main3Activity.class

package com.example.gqiu.helloworld;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RemoteViews;

public class Main3Activity extends AppCompatActivity {

    private LinearLayout linearLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
                startActivity(new Intent(Main3Activity.this, Main2Activity.class));
            }
        });

        linearLayout = findViewById(R.id.linearLayout);
        IntentFilter filter = new IntentFilter(Main2Activity.MY_REMOTE_ACTION);
        registerReceiver(mRemoteBroadcastReceiver,filter);
    }

    private BroadcastReceiver mRemoteBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("lgq","broadcast receiver:");
            RemoteViews remoteViews = intent.getParcelableExtra(Main2Activity.EXTRA_REMOTE_VIEWS);
            if (remoteViews != null){
                updateUi(remoteViews);
            }
        }
    };

    private void updateUi(RemoteViews remoteViews) {
        View view = remoteViews.apply(this, linearLayout);
        linearLayout.addView(view);
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(mRemoteBroadcastReceiver);
        super.onDestroy();
    }
}
Main2Activity.class

package com.example.gqiu.helloworld;

import android.app.PendingIntent;
import android.app.RemoteAction;
import android.content.Intent;
import android.os.Bundle;
import android.os.Process;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.RemoteViews;

public class Main2Activity extends AppCompatActivity {

    public static final String EXTRA_REMOTE_VIEWS  = "remote_views";
    public static final String MY_REMOTE_ACTION = "remote_action";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //RemoteViews的布局
        final RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_remote_notification);
        //设置RemoteViews显示的内容
        remoteViews.setTextViewText(R.id.msgTextView, "msg from progress:" + Process.myPid());
        //设置RemoteViews的点击事件---这里点击后再次返回到当前activity
        final PendingIntent openActivity2PendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), Main2Activity.class),
                PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.msgTextView, openActivity2PendingIntent);

        //发送广播的方式通知另外线程更新ui
        Intent intent = new Intent();
        intent.setAction(MY_REMOTE_ACTION);
        intent.putExtra(EXTRA_REMOTE_VIEWS, remoteViews);
        sendBroadcast(intent);
    }

}
以上就是RemoteViews的简单使用了,很简单,一颗赛艇。
学习于《android开发艺术探索》所理解写的demo

你可能感兴趣的:(android)