android 中的RemoteView添加点击操作,是通过延迟意图PentingIntent来执行的.
应用场景: 通知栏与桌面小部件,更新不同进程间的界面
桌面部件与通知栏分别由AppWidgetManager 与 NotificationManager来管理.
分别与systemService进程中的AppWidgetServer和NotificationManagerServer进行通讯
所以,才需要RemoteView来更新界面.RemoteView实现了Paracelable,通过Bindler传递到
systemService进程中.
通知栏:
1.现在清单文件中做如下配置
<!-- appwidget的receiver -->
<receiver android:name="com.wmh.mobilesafe.receiver.AppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info" />
</receiver>
2.配置@xml/appwidget_info文件,xml文件夹是res文件夹的子文件夹
2.1 先介绍各个属性的含义
<!-- <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dp"
android:minHeight="72dp"//能被调整的最小宽高,若大于minWidth minHeight 则忽略
android:updatePeriodMillis="86400000"//更新周期,毫秒,最短默认半小时
android:previewImage="@drawable/preview"//选择部件时 展示的图像,3.0以上使用,默认是ic_launcher
android:initialLayout="@layout/example_appwidget"//布局文件
android:configure="com.example.android.ExampleAppWidgetConfigure"//添加widget之前,先跳转到配置的activity进行相关参数配置
android:resizeMode="horizontal|vertical"//widget可以被拉伸的方向。horizontal表示可以水平拉伸,vertical表示可以竖直拉伸
android:widgetCategory="home_screen|keyguard"//分别在屏幕主页和锁屏状态也能显示(4.2+系统才支持)
android:initialKeyguardLayout="@layout/example_keyguard"//锁屏状态显示的样式(4.2+系统才支持)
>
</appwidget-provider> -->
2.2下面是我的配置
<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="294dp"
android:minHeight="72dp"
android:initialLayout="@layout/process_widget"
>
</appwidget-provider>
3.配置广播接收者
public class AppWidgetProvider extends android.appwidget.AppWidgetProvider{
/*
*1.onEnabled 创建第一个窗体小部件的方法的时候调用
*2.onUpdate 创建多一个窗体小部件的方法
*3.onAppWidgetOptionsChanged 当窗体小部件的宽高方式改变的时候调用,创建的时候也调用
*4.onDeleted 删除小部件调用的方法
*5.onDisabled 删除最后一个窗体小部件调用的方法
*/
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
//创建第一个窗体小部件的方法
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
//开启服务
context.startService(new Intent(context,UpdateWidgetService.class));
}
//删除最后一个窗体小部件调用的方法
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
//关闭服务
}
}
4.配置服务,用来实时更新窗体小部件
public class UpdateWidgetService extends Service {
private Timer timer;
private TimerTask task;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
// 管理进程总数和可用内存数的更新
startTimer();
}
private void startTimer() {
timer = new Timer();
task = new TimerTask() {
@Override
public void run() {
// UI定时更新
UpdateAppWidget();
}
};
timer.scheduleAtFixedRate(task, 0, 2000);// 比schedule要好
}
protected void UpdateAppWidget() {
// 1.获取APPwidget的对象
AppWidgetManager aWM = AppWidgetManager.getInstance(this);
// 2.获取窗体小部件的布局转化成的View
RemoteViews view = new RemoteViews(getPackageName(), R.layout.process_widget);
// 3.给窗体小部件view对象,内部空间赋值
view.setTextViewText(R.id.tv_process_count,
"进程数:" + ProcessInfoProvider.getProcessCount(getApplicationContext()));
String availMemory = Formatter.formatFileSize(getApplicationContext(),
ProcessInfoProvider.getAvailMemory(getApplicationContext()));
view.setTextViewText(R.id.tv_process_memory, "可用内存:" + availMemory);
// 设置点击事件进入应用 PendingIntent延期的意图
Intent intent1 = new Intent();
intent1.setAction("android.intent.action.splash");
intent1.addCategory("android.intent.category.DEFAULT");
// FLAG_CANCEL_CURRENT 点了就消失
PendingIntent pendingIntent1 = PendingIntent.getActivity(this, 0, intent1, PendingIntent.FLAG_CANCEL_CURRENT);
view.setOnClickPendingIntent(R.id.ll_widget_root, pendingIntent1);
//通过延期意图发送广播,在广播接收者中杀死进程
Intent broadCastIntent = new Intent("android.intent.action.KILL_BACKGROUND_PROCESS");
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(getApplicationContext(), 0, broadCastIntent, PendingIntent.FLAG_CANCEL_CURRENT);
view.setOnClickPendingIntent(R.id.bt_clear, pendingIntent2);
// 更新的操作 后面的参数是窗体小部件对应的的广播接收者 attention:这一步写在最后边
ComponentName componentName = new ComponentName(getApplicationContext(), AppWidgetProvider.class);
aWM.updateAppWidget(componentName, view);
}
@Override
public void onDestroy() {
super.onDestroy();
if (timer != null && task != null) {
timer.cancel();
task.cancel();
}
}
}
5.配置清理进程的广播接收者
public class killBackGroundReicever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//接收广播,清理进程
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();
for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) {
am.killBackgroundProcesses(runningAppProcessInfo.processName);
}
}
}