广播不能进行持久操作,因此获取到小部件的广播以后,发送服务,在服务里面处理窗口小部件,清理按键的时候需要获取到清理进程的广播,然后在按键中监听,出发广播,进行清理操作,。窗口小部件更新UI的时候是通过初始化远程的view来设置UI的。
首先需要在清单文件中注册窗口小部件的文件,和2个广播接收者
<!-- 清理所有的进程 -->
<receiver android:name="com.ldw.safe.receiver.KillProcessAllReceiver" >
<intent-filter>
<action android:name="com.ldw.safe" />
</intent-filter>
</receiver>
<!-- 桌面小部件的配置 -->
<receiver android:name="com.ldw.safe.receiver.MyAppWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
/res/xml/example_appwidget_info文件
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/process_widget"
android:minHeight="72.0dip"
android:minWidth="294.0dip"
android:updatePeriodMillis="0" />
update时间设置成0,这样自己可以设置更新时间
process_widget.xml窗口小部件的UI
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/widget_bg_portrait"
android:gravity="center_vertical" >
<LinearLayout
android:layout_width="0.0dip"
android:layout_height="fill_parent"
android:layout_marginLeft="5.0dip"
android:layout_weight="1.0"
android:background="@drawable/widget_bg_portrait_child"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingBottom="3.0dip"
android:paddingTop="3.0dip" >
<TextView
android:id="@+id/process_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10.0dip"
android:textSize="16sp"
android:textColor="#ffffff"
/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1.0dip"
android:layout_marginTop="1.0dip"
android:background="@drawable/widget_bg_portrait_child_divider" />
<TextView
android:id="@+id/process_memory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10.0dip"
android:textSize="16sp"
android:textColor="#ffffff"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<ImageView
android:layout_width="20.0dip"
android:layout_height="20.0dip"
android:src="@drawable/main_icon" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textColor="#ffffffff" />
</LinearLayout>
<Button
android:id="@+id/btn_clear"
android:layout_width="90.0dip"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginTop="5.0dip"
android:background="@drawable/button"
android:text="一键清理"
/>
</LinearLayout>
</LinearLayout>
MyAppWidget.java桌面小部件的广播接收者,接受到广播以后跳转到服务中进行持久化处理
package com.ldw.safe.receiver;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import com.ldw.safe.service.KillProcesWidgetService;
/*
* 桌面小部件的广播接收者
*/
public class MyAppWidget extends AppWidgetProvider {
/**
* 第一次创建的时候才会调用当前的生命周期的方法
* 开启一个服务,实时更新进程相关
* 当前的广播的生命周期只有10秒钟。
* 不能做耗时的操作
*/
@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
super.onEnabled(context);
System.out.println("onEnabled");
//开启杀死进程的服务服务
Intent intent = new Intent(context,KillProcesWidgetService.class);
context.startService(intent);
}
/**
* 当桌面上面所有的桌面小控件都删除的时候才调用当前这个方法
*/
@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
super.onDisabled(context);
Intent intent = new Intent(context,KillProcesWidgetService.class);
context.stopService(intent);
System.out.println("onDisabled");
}
}
KillProcesWidgetService.java在服务中进行相关的处理操作,定时清理操作和,按钮清理操作,并更新界面的UI
package com.ldw.safe.service;
import java.util.Timer;
import java.util.TimerTask;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
import android.text.format.Formatter;
import android.widget.RemoteViews;
import com.ldw.safe.R;
import com.ldw.safe.receiver.MyAppWidget;
import com.ldw.safe.utils.SystemInfoUtils;
/*
* 创建一个服务,获取到进程里面的相关信息
*/
public class KillProcesWidgetService extends Service {
private AppWidgetManager widgetManager;
private Timer timer;
private TimerTask timerTask;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
//桌面小控件的管理者,通过这个来更新小部件的界面
widgetManager = AppWidgetManager.getInstance(this);
//每隔5秒钟更新一次桌面
//初始化定时器
timer = new Timer();
//初始化一个定时任务
timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("KillProcesWidgetService");
//这个是把当前的布局文件添加进行
/**
* 初始化一个远程的view
* Remote 远程
*/
RemoteViews views = new RemoteViews(getPackageName(), R.layout.process_widget);
/**
* 需要注意。这个里面findingviewyid这个方法
* 设置当前文本里面一共有多少个进程
*/
int processCount = SystemInfoUtils.getProcessCount(getApplicationContext());
//设置文本
views.setTextViewText(R.id.process_count,"正在运行的软件:" + String.valueOf(processCount));
//获取到当前手机上面的可用内存
long availMem = SystemInfoUtils.getAvailMem(getApplicationContext());
views.setTextViewText(R.id.process_memory, "可用内存:" +Formatter.formatFileSize(getApplicationContext(), availMem));
Intent intent = new Intent();
//发送一个隐式意图
intent.setAction("com.ldw.safe");
//接收一个意图,同时通过getBroadcast获取到清理进程的广播
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
//远程的view设置点击时间设置点击事件
views.setOnClickPendingIntent(R.id.btn_clear, pendingIntent);
//第一个参数表示上下文
//第二个参数表示当前有哪一个广播进行去处理当前的桌面小控件
ComponentName provider = new ComponentName(getApplicationContext(), MyAppWidget.class);
//更新桌面UI
widgetManager.updateAppWidget(provider, views);
}
};
//从0开始。每隔5秒钟更新一次
timer.schedule(timerTask, 0, 5000);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//优化代码
if(timer != null || timerTask != null){
timer.cancel();
timerTask.cancel();
timer = null;
timerTask = null;
}
}
}
KillProcessAllReceiver.java按钮中通过发送广播进行内存的清理
package com.ldw.safe.receiver;
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/*
* 清理所有的进程
*/
public class KillProcessAllReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//ActivityManager获取到管理者对象
ActivityManager activityManager = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
//得到手机上面正在运行的进程
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for (RunningAppProcessInfo runningAppProcessInfo : appProcesses) {
//杀死所有的进程
activityManager.killBackgroundProcesses(runningAppProcessInfo.processName);
}
Toast.makeText(context, "清理完毕", 0).show();
}
}