桌面小控件(Widget)--之清理进程
桌面小控件(Widget)--之清理进程
首先,简单的说一下什么是Widget,Widget是在Android系统界面中添加的小部件。那么在android中有一个系统内置服务来专门管理widget,该服务为AppWidgetManager。
建立widget的步骤如下:
1.建立一个工程,然后写一个类继承AppWidgetProvider并重写onEnabled(),onUpdate(),onDisabled()方法
classTimeWidgetProviderextendsAppWigetProvider
{
}
2.AppWigetProvider是一个广播接者。在配置文件中进行配置:
<receiverandroid:name=".receiver.MyWidget">
<intent-filter>
<actionandroid:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-dataandroid:name="android.appwidget.provider“
android:resource="@xml/appwidget_info"/>
</receiver>
3.在res文件夹下建一个xml文件夹,放置一个appwidget_info.xml该文件为widget的界面
在桌上第一个添加该widget时系统会发出一个广播,该广播会被我们定义的TimeWidgetProvider所接收,并执行onEnabled()方法,该widget添加后会发出一个广播,该广播的类型为:
android.appwidget.action.APPWIDGET_UPDATE会执行onUpdate()方法,当桌面上同类型的Widget的最后一个被删除时会执行onDisabled()方法.
在onUpate()方法中可以更改widget界面上的内容.
效果图如下:
当我们点击一键清理的时候,就会把手机的一些正在运行的进程结束掉,当然用户系统在没有获得root权限之前是不可以结束掉的。
步骤一:
写一个类,继承AppWidgetProvider
package cn.cbd.clean;import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.Context;import android.content.Intent;public class CleanWidget extends AppWidgetProvider{private Intent service;@Overridepublic void onDeleted(Context context, int[] appWidgetIds){super.onDeleted(context, appWidgetIds);}@Overridepublic void onDisabled(Context context){//停止服务service = new Intent(context, MyService.class);context.stopService(service);super.onDisabled(context);}@Overridepublic void onEnabled(Context context){//开启服务service = new Intent(context, MyService.class);context.startService(service);super.onEnabled(context);}@Overridepublic void onReceive(Context context, Intent intent){super.onReceive(context, intent);}@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds){// TODO Auto-generated method stubsuper.onUpdate(context, appWidgetManager, appWidgetIds);}}
AppWidgetProvider也是一个广播接收者,所以我们要在清单文件中对CleanWidget进行配置
<applicationandroid:icon="@drawable/ic_launcher"android:label="@string/app_name" ><receiver android:name=".CleanWidget" ><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /></intent-filter><!-- meta-data 携带数据 传递数据用的 --><meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/example_appwidget_info" /></receiver>
在类CleanWidget中我们可以看到,我们在ouEnabled()方法中开启一个服务,在onDisabled()中关闭这个服务,当我们把小控件拖到桌面上的时候,就会先执行onReceive然后紧接着执行onEnable()方法,当我们把桌面上相同的最后一个控件删除,就会执行onDisabled()方法。
那我们在服务中做哪些事情呢?
package cn.cbd.clean;import java.util.ArrayList;import java.util.List;import java.util.Timer;import java.util.TimerTask;import android.app.ActivityManager;import android.app.PendingIntent;import android.app.Service;import android.app.ActivityManager.RunningAppProcessInfo;import android.appwidget.AppWidgetManager;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.os.IBinder;import android.text.format.Formatter;import android.widget.RemoteViews;public class MyService extends Service{private List<String> packageNames;private static final String BUTTON_KILLPROCESS = "cn.cbd.KILLPROCESS";private Timer timer;@Overridepublic void onCreate(){//新建一个计时器,来不断的监听手机正在运行程序的个数是否发生改变timer = new Timer();timer.schedule(new TimerTask(){public void run(){//新建一个String类型集合,来存放正在运行程序的包名(我们结束进程是需要通过应用程序的包名来结束的)。packageNames = new ArrayList<String>();//获取AppWidgetManager控件管理者对象AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);List<RunningAppProcessInfo> infos = am.getRunningAppProcesses();for (RunningAppProcessInfo info : infos){packageNames.add(info.processName);}//对于本应用来说,桌面的控件属于远程View了,所以我们需要一个RemoteViews对象,来管理我们自定义ViewRemoteViews views = new RemoteViews(getApplicationContext().getPackageName(), R.layout.memorycleanning);//设置控件上的文字内容views.setTextViewText(R.id.tv_runningAppNums, "正在运行程序有"+ (packageNames.size() + "个"));views.setTextViewText(R.id.tv_availableMemory,"剩余内存"+ Formatter.formatFileSize(getApplicationContext(),MemoryUtil.getAvailableMem(getApplicationContext())));//当我们点击一键清理按钮时发送一个自定义广播,类型为cn.cbd.KILLPROCESS 配置文件中也要进行相应的配置Intent intent = new Intent();intent.setAction(BUTTON_KILLPROCESS);PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);//为小控件上的按钮设置点击事件views.setOnClickPendingIntent(R.id.btn_clean, pendingIntent);ComponentName componentName = new ComponentName(getApplicationContext(), CleanWidget.class);//更新AppAidget 也就是更新桌面控件中的内容appWidgetManager.updateAppWidget(componentName, views);}}, 0, 10);super.onCreate();}@Overridepublic IBinder onBind(Intent intent){return null;}@Overridepublic void onDestroy(){super.onDestroy();}}
自定义广播在配置文件中的配置情况
<!-- 广播接收者 自定义了一种广播 --><receiver android:name=".KillProcessBroadcaseReceiver" ><intent-filter><action android:name="cn.cbd.KILLPROCESS" /></intent-filter></receiver>
此时,显然我们要写一个广播接收者,来接收我们这种类型的广播
package cn.cbd.clean;import java.util.ArrayList;import java.util.List;import android.app.ActivityManager;import android.app.ActivityManager.RunningAppProcessInfo;import android.appwidget.AppWidgetManager;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.text.format.Formatter;import android.widget.RemoteViews;public class KillProcessBroadcaseReceiver extends BroadcastReceiver{private List<String> packageNames;@Overridepublic void onReceive(Context context, Intent intent){packageNames = new ArrayList<String>();RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.memorycleanning);AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);List<RunningAppProcessInfo> infos = am.getRunningAppProcesses();for (RunningAppProcessInfo info : infos){packageNames.add(info.processName);}String action = intent.getAction();if (action.equals("cn.cbd.KILLPROCESS")){for (String packageName : packageNames){am.killBackgroundProcesses(packageName);}ComponentName componentName = new ComponentName(context,CleanWidget.class);views.setTextViewText(R.id.tv_runningAppNums, "正在运行程序有"+ packageNames.size() + "个");views.setTextViewText(R.id.tv_availableMemory,"剩余内存"+ Formatter.formatFileSize(context,MemoryUtil.getAvailableMem(context)));appWidgetManager.updateAppWidget(componentName, views);}}}
在这个广播中,我们会用到一个工具类,就是获取手机RAM剩余内存大小的。这个类是我们自定义的工具类。
package cn.cbd.clean;import android.app.ActivityManager;import android.app.ActivityManager.MemoryInfo;import android.content.Context;/*** 工具类,用来获取手机剩余内存大小* @author Administrator**/public class MemoryUtil{//Formatter.formatFileSize(this,availaleMemory) 格式化public static long getAvailableMem(Context context){ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);MemoryInfo outInfo= new MemoryInfo();am.getMemoryInfo(outInfo);return outInfo.availMem;}}
到此呢,我们这个清理手机进程的小控件已经完成。现在呢,我整理一下这个小项目的思路:
1.得到一个Widget对象(继承AppWidgetProvider)
2.开启一个服务,来更新控件上数据的变化
3.在服务中定义一个广播,当我们点击“一键清理”按钮时,就会发送一个广播。这时候呢,需要我们写一个广播接收者,来接收我们定义的这种类型的广播。
4.在广播中,我们做杀掉进程的操作。
更多相关文章
- 详解如何让Android(安卓)UI设计性能更高效
- 基于Android平台下的科学计算器
- android 7.0 ,6.0本地多语言切换失效
- Android底部菜单栏的实现
- android 中定时器的几种用法总结
- Android(安卓)中TextView 添加超链接
- android内核编译方法 转载
- android中MediaPlayer的用法
- Android梳理不常用widget篇