提供了一组基础的操作用于跨进程更新界面的View,常应用在通知栏和桌面小部件
1. RemoteViews的应用
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.send_notification);
btn.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onClick(View view) {
send_notification();
}
});
}
@RequiresApi(api = Build.VERSION_CODES.O)
public void send_notification(){
NotificationChannel channel = new NotificationChannel("1","my_channel", NotificationManager.IMPORTANCE_DEFAULT);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentText("Notification").setWhen(System.currentTimeMillis());
Intent intent = new Intent(this, secondActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notification);
remoteViews.setTextViewText(R.id.msg,"chapter_5");
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , new Intent(this, secondActivity.class),PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.click, pendingIntent);
builder.setCustomContentView(remoteViews);
builder.setContentIntent(pi);
builder.setSmallIcon(R.drawable.ic_launcher_background);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);
builder.setChannelId("1");
Notification notification = builder.build();
manager.notify(1,notification);
}
}
- 注意:适配问题,Android Q以上需要设置
channel
2. PendingIntent概述
一种处于
pending
状态的意图,也就是说接下来有一个Intent
将在某一个待定的时刻发生
- 因为
RemoteViews
运行在远程进程中,因此不能用setOnClickListener
方法来设置单击事件,要想设置则必须使用PendingIntent
-
PendingIntent
支持三种待定意图:启动Activity
、启动Service
和发送广播
方法名 | 作用 |
---|---|
getActivity(Context context, int requestCode, Intent intent, int flags) |
获得一个PendingIntent,当该意图发生时,相当于Context.startActivity(Intent)
|
getService(Context context, int requestCode, Intent intent, int flags) |
获得一个PendingIntent,当该意图发生时,相当于Context.startService(Intent)
|
getBroadcast(Context context, int requestCode, Intent intent, int flags) |
获得一个PendingIntent,当该意图发生时,相当于Context.sendBroadcast(Intent)
|
-
PendingIntent
的匹配规则:Intent
相同,且requestCode
相同 -
Intent
匹配规则:ComponentName
和intent-filter
相同 -
flags
常见的类型:FLAG_ONE_SHOT
,FLAG_NO_CREATE
,FLAG_CANCEL_CURRENT
,FLAG_UPDATE_CURRENT
FLAG_ONE_SHOT
:当前描述的PendingIntent
只能被使用一次,然后就会自动cancel
FLAG_NO_CREATE
:当前描述的PendingIntent
不能被主动创建
FLAG_CANCEL_CURRENT
:当前描述的PendingIntent
如果已经存在,那么它们都会被cancel,然后系统会创建一个新的PendingIntent
FLAG_UPDATE_CURRENT
:当前描述的PendingIntent
如果已经存在,那么它就会被更新

3. RemoteViews的内部机制
构造函数:RemoteViews(String packageName, int layoutId)
- 支持的
layout
:FrameLayout
,LinearLayout
,RelativeLayout
,GridLayout
- 支持的
View
:AnalogClock
,Button
,Chronometer
,ImageButton
,ImageView
,ProgressBar
,TextView
,ViewFlipper
,ListView
,GridView
,StackView
,AdapterViewFlipper
,ViewStub
RemoteViews
访问View
元素只能通过一系列set
元素来完成
方法名 | 作用 |
---|---|
setTextView() |
设置TextView的文本 |
setTextViewTextSize() |
设置TextView的字体大小 |
setTextColor() |
设置TextView的字体颜色 |
setImageResource() |
设置ImageView的图片资源 |
setOnClickListener() |
设置ImageView的图片资源 |

- 首先通过一系列
set
方法将View
操作保存为一系列的Action
存储起来 - 然后在远端进程中通过
remoteViews
的apply
方法来更新UI界面,实现远程刷新界面的效果
作用:
- 不需要定义大量Binder接口
- 避免了大量的IPC操作,提高了程序的型嫩
4. RemoteViews Demo
BroadCast.java
public class BroadCast extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broad_cast);
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.simulated_notification);
remoteViews.setTextViewText(R.id.textForTest, "msg from Process");
PendingIntent pi = PendingIntent.getActivity(this,0, new Intent(this, MainActivity.class),PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.textForTest, pi);
Intent intent = new Intent("com.example.remoteviews");
intent.putExtra("com.example.remoteviews", remoteViews); //在发送intent的时候将remoteViews发送出去
sendBroadcast(intent);
Log.d("guanzihan","已发送");
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private LinearLayout mRemoteViewsContent;
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
RemoteViews remoteViews = intent.getParcelableExtra("com.example.remoteviews");
if(remoteViews != null){
updateUI(remoteViews);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
public void initView(){
mRemoteViewsContent = (LinearLayout)findViewById(R.id.remoteViews_content);
IntentFilter intentFilter = new IntentFilter("com.example.remoteviews");
registerReceiver(broadcastReceiver,intentFilter);
startActivity(new Intent(this, BroadCast.class));
}
public void updateUI(RemoteViews remoteViews){
View view = remoteViews.apply(this, mRemoteViewsContent);
mRemoteViewsContent.addView(view);
}
}

网友评论