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
<activity
android:name=".Main2Activity"
android:label="@string/title_activity_main2"
android:theme="@style/AppTheme.NoActionBar" >
</activity>
<activity
android:name=".Main3Activity"
android:label="@string/title_activity_main3"
android:process=":main3activity"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
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允许在不同进程中更新界面,适用于界面更新频繁的情况。它不支持所有View类型,仅限于基础组件。本文通过一个模拟示例,演示了如何使用RemoteViews实现类似通知栏和桌面小工具的跨进程更新,简化了AIDL可能带来的复杂性和效率问题。

2227

被折叠的 条评论
为什么被折叠?



