金山手机卫士:进程清理

首先看一下:UI效果:

   金山手机卫士:进程清理_第1张图片       金山手机卫士:进程清理_第2张图片     金山手机卫士:进程清理_第3张图片

学习了进程管理方面的内容:

进入进程管理后:可以查看用户进程和系统进程,

ListView中设有复选框,可实现全选、反选效果

清理功能可以清理进程

在设置里面有是否显示系统进程和锁屏清理等功能。



先看看主界面的配置文件:挺有意义学习学习的

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView 
        android:background="#8866ff00"
        android:textSize="22sp"
        android:textColor="#000000"
        android:gravity="center"
        android:id="@+id/textView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:height="55dip"
        android:text="进程管理"
        />
    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
         >
        <TextView 
        android:id="@+id/tv_process_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#000000"
        android:text="运行中的进程"  
            />
        <TextView 
        android:id="@+id/tv_mem_info"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#000000"
        android:text="剩余/总内存"  
            />
        </RelativeLayout>
        <FrameLayout 
            android:layout_weight="100"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            >
        <LinearLayout 
            android:id="@+id/ll_loading"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical"
            android:gravity="center"
            android:visibility="invisible"
            >
            <ProgressBar 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                />
            <TextView 
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="正在加载程序信息。。。"
                />
        </LinearLayout>
        <ListView 
            android:overScrollMode="never"
            android:fastScrollEnabled="true"
            android:id="@+id/lv_task_manager"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            ></ListView>
          <TextView 
                android:id="@+id/tv_status"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="用户程序:"
                android:textColor="#ffffff"
                android:background="#ff888888"
                />
        </FrameLayout>
        <LinearLayout 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            >
            <Button 
               android:onClick="selectAll"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="全选"
                />
            <Button
            android:onClick="selectOppo"
            android:layout_width="0dip" 
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="反选"
                />
            <Button 
                android:onClick="killAll"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="清理"
                />
            <Button 
                android:onClick="enterSetting"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="设置"
                />
        </LinearLayout>
</LinearLayout>
效果如下:

金山手机卫士:进程清理_第4张图片这个布局文件挺值得学习的,是怎么布局,实现了这样的效果,这些非常重要。



ListView的滚动事件:OnScrollListener

	lv_task_manager.setOnScrollListener(new OnScrollListener() {
			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				// TODO Auto-generated method stub
			}
			@Override
			public void onScroll(AbsListView view, int <strong>firstVisibleItem</strong>,
					int visibleItemCount, int totalItemCount) {
				if(userTaskInfos!=null&systemTaskInfos!=null){
					if(firstVisibleItem>userTaskInfos.size()){
						tv_status.setText("系统进程:"+systemTaskInfos.size()+"个");
						
					}else{
						tv_status.setText("用户进程:"+userTaskInfos.size()+"个");
					}
				}
			}
		});

这里用到了firstVisibleItem变量,这里面visibleItemCount 、totalItemCount参数。也非常重要。


ListView的点击事件:

		lv_task_manager.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				TaskInfo taskInfo;
				if(position==0){  //用户进程的标签
					return ;
				}else if(position==(userTaskInfos.size()+1)){
					return ;
				}else if(position<=userTaskInfos.size()){
					taskInfo=userTaskInfos.get(position-1);
				}else{
					taskInfo=systemTaskInfos.get(position-1-userTaskInfos.size()-1);
				}
				if(getPackageName().equals(taskInfo.getPackname())){
					return;
				}
				
				ViewHolder holder=(ViewHolder) view.getTag();
				if(taskInfo.isChecked()){
					taskInfo.setChecked(false);
					holder.cb_status.setChecked(false);
				}else{
					taskInfo.setChecked(true);
					holder.cb_status.setChecked(true);
				}
				
			}
		});
		
	}

这里利用参数view设置复选框的状态。


setTitle和 fillData方法来填充数据:编写代码过程中尽量封装起来复用。

private void setTitle() {
	    processCount=SystemInfoUtils.getRunningProcessCount(this);
		tv_process_count.setText("运行中的进程:"+processCount+"个");
		
		availMem=SystemInfoUtils.getAvailMem(this);
	    totalMem=SystemInfoUtils.getTotalMem(this);
		tv_mem_info.setText("剩余/总内存:"+Formatter.formatFileSize(this, availMem)+"/"+Formatter.formatFileSize(this, totalMem));
	}
	
	private void fillData() {

		ll_loading.setVisibility(View.VISIBLE);
		new Thread(){
			public void run(){
				allTaskInfos=TaskInfoProvider.getTaskInfos(getApplicationContext());
				userTaskInfos =new ArrayList<TaskInfo>();
				systemTaskInfos=new ArrayList<TaskInfo>();
				for(TaskInfo info:allTaskInfos){
					if(info.isUserTask()){
						userTaskInfos.add(info);
					}else{
						systemTaskInfos.add(info);
						
					}
				}
				
				
				//设置更新界面
				runOnUiThread(new Runnable(){
					@Override
					public void run() {
						ll_loading.setVisibility(View.INVISIBLE);

						if(adapter==null){
							adapter=new TaskManagerAdapter();
							lv_task_manager.setAdapter(adapter);

						}else{
							adapter.notifyDataSetChanged();
						}
						setTitle();
					}
				});
			}
		}.start();
	}


适配器:

private class TaskManagerAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			SharedPreferences sp=getSharedPreferences("config", MODE_PRIVATE);;
			if(sp.getBoolean("showsystem", false)){
				return userTaskInfos.size()+1+systemTaskInfos.size()+1;
			}else{
				return userTaskInfos.size()+1;
			}
			
		
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			TaskInfo taskInfo;
			if(position==0){  //用户进程的标签
				TextView tv=new TextView(getApplicationContext());
				tv.setBackgroundColor(Color.GRAY);
				tv.setTextColor(Color.WHITE);
				tv.setText("用户进程:"+userTaskInfos.size()+"个");
				return tv;
			}else if(position==(userTaskInfos.size()+1)){
				TextView tv=new TextView(getApplicationContext());
				tv.setBackgroundColor(Color.GRAY);
				tv.setTextColor(Color.WHITE);
				tv.setText("系统进程:"+systemTaskInfos.size()+"个");
				return tv;
			}else if(position<=userTaskInfos.size()){
				taskInfo=userTaskInfos.get(position-1);
			}else{
				taskInfo=systemTaskInfos.get(position-1-userTaskInfos.size()-1);
			}
			View view;
			ViewHolder holder;
			
			if(convertView!=null&&convertView instanceof RelativeLayout){
				view=convertView;
				holder=(ViewHolder) view.getTag();
			}else{
				view=View.inflate(getApplicationContext(),R.layout.list_item_taskinfo,null);
				holder=new ViewHolder();
				holder.iv_icon =(ImageView) view.findViewById(R.id.iv_task_icon);
				holder.tv_name=(TextView) view.findViewById(R.id.tv_task_name);
				holder.tv_memsize=(TextView) view.findViewById(R.id.tv_task_memsize);
				holder.cb_status= (CheckBox) view.findViewById(R.id.cb_status);
			    
				view.setTag(holder);
			}
			holder.iv_icon.setImageDrawable(taskInfo.getIcon());
			holder.tv_name.setText(taskInfo.getName());
			holder.tv_memsize.setText("内存占用:"+Formatter.formatShortFileSize(getApplicationContext(), taskInfo.getMemsize()));
			holder.cb_status.setChecked(taskInfo.isChecked());
			if(getPackageName().equals(taskInfo.getPackname())){
				holder.cb_status.setVisibility(View.INVISIBLE);
			}else{
				holder.cb_status.setVisibility(View.VISIBLE);
			}
			
			return view;
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return 0;
		}
	}

Android的API提供了将byte装换成mib格式:Formatter.formatShortFileSize(getApplicationContext(), taskInfo.getMemsize()));


四个按钮的单击事件:

     让自己这个程序不可选【复选框】

      

if(getPackageName().equals(info.getPackname())){
				continue;
}


适配器状态刷新的时候,用到这个API,会经常用到的:adapter.notifyDataSetChanged();


反选的逻辑非常简单:
/*
	 * 选择反选
	 */
	public void selectOppo(View view){
		for(TaskInfo info:allTaskInfos){
			if(getPackageName().equals(info.getPackname())){
				continue;
			}
			info.setChecked(!info.isChecked());
		}
		adapter.notifyDataSetChanged();
	}



一键清理逻辑:理解是怎么杀死进程,实现清理的【获得Activity管理器,killBackgroundProcesses()即可】

/*
	 * 一键清理
	 */
	public void killAll(View view){
		<strong>ActivityManager am=(ActivityManager) getSystemService(ACTIVITY_SERVICE);</strong>
		int count=0;
		long savedMem=0;
		//记录那些被杀死的条目
		List<TaskInfo> killedTaskinfos=new ArrayList<TaskInfo>();
		for(TaskInfo info:allTaskInfos){
			if(info.isChecked()){
				am.killBackgroundProcesses(info.getPackname());
				if(info.isUserTask()){
					userTaskInfos.remove(info);
				}else{
					systemTaskInfos.remove(info);
				}
				killedTaskinfos.add(info);
				count++;
				savedMem+=info.getMemsize();
			}
		}
		allTaskInfos.remove(killedTaskinfos);
		adapter.notifyDataSetChanged();
		Toast.makeText(this,"杀死了"+count+"个进程,释放了"+Formatter.formatFileSize(this, savedMem)+"的内存",1).show();
		//count++;
		//savedMem+=info.getMemsize();
		
		processCount-=count;
	    availMem+=savedMem;
	    tv_process_count.setText("运行中的进程:"+processCount+"个");
		tv_mem_info.setText("剩余/总内存:"+Formatter.formatFileSize(this, availMem)+"/"+Formatter.formatFileSize(this, totalMem));

		
		//fillData();
	}

设置逻辑:要理解为什么会用到startActivityForResult()    

/*
	 * 进入设置
	 */
	public void enterSetting(View view){
		Intent intent=new Intent(this, TaskSettingActivity.class);
		startActivityForResult(intent, 0);
		
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		adapter.notifyDataSetChanged();
		super.onActivityResult(requestCode, resultCode, data);
	}
	



设置界面的Activity

public class TaskSettingActivity extends Activity{

	private CheckBox cb_show_system;
	private CheckBox cb_auto_clean;
	private SharedPreferences sp;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_task_setting);
	    sp=getSharedPreferences("config", MODE_PRIVATE);
		cb_show_system=(CheckBox) findViewById(R.id.cb_show_system);
		cb_auto_clean=(CheckBox) findViewById(R.id.cb_auto_clean);
		cb_show_system.setChecked(sp.getBoolean("showsystem", false));
		cb_show_system.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				// TODO Auto-generated method stub
				Editor editor=sp.edit();
				editor.putBoolean("showsystem", isChecked);
				editor.commit();
				
			}
		});
		
		cb_auto_clean.setOnCheckedChangeListener(new OnCheckedChangeListener(){

			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {
                 //锁屏的广播事件是一个特殊的广播事件,在清代文件配置中广播接收者不会生效
				//只能在代码里面接收里面注册才会生效:在服务里面实现
				Intent intent=new Intent(TaskSettingActivity.this,AutoCleanService.class);
				if(isChecked){
					startService(intent);
				}else{
					stopService(intent);
				}
			}
		});
		
	}
	@Override
	protected void onStart() {
       boolean running=ServiceUtils.isServiceRunning(this, "com.example.mobilesafe.service.AutoCleanService");
         cb_auto_clean.setChecked(running);
		super.onStart();
	}
}

设置系统进程里面用到了Editor来保存变量。

锁屏清理进程里面用到了一个服务里面开启广播【非常重要】



通过在onCreate()方法里面获取服务状态来显示复选框的状态。

@Override
	protected void onStart() {
       boolean running=ServiceUtils.isServiceRunning(this, "com.example.mobilesafe.service.AutoCleanService");
         cb_auto_clean.setChecked(running);
		super.onStart();
	}


服务里面注册广播接收者【重点理解服务和广播的概念及真么在服务里面注册广播】

public class AutoCleanService extends Service {

	private ScreenOffReceiver receiver;
	private ActivityManager am;
	@Override
	public IBinder onBind(Intent intent) {

		return null;
	}
	
	@Override
	public void onCreate() {
		am=(ActivityManager) getSystemService(ACTIVITY_SERVICE);
		receiver=new ScreenOffReceiver();
		//System.out.println("广播注册成功");
		registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		
		unregisterReceiver(receiver);
		//System.out.println("广播销毁成功");
		receiver=null;
		super.onDestroy();
	}
	
	private class ScreenOffReceiver extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			//得到所有的进程
			//System.out.println("广播执行成功");
			List<RunningAppProcessInfo> infos=am.getRunningAppProcesses();
			for(RunningAppProcessInfo info:infos){
				am.killBackgroundProcesses(info.processName);
			}
		}
	}
}


用到的查看内存及进程相关的非常重要的工具类:

/*
 * 系统信息的工具类
 */
public class SystemInfoUtils {

	/*
	 * 获取正在运行的进程的数量
	 */
	//PackageManager  包管理器,相当于程序管理器:静态的内容
	//ActivityManager 进程管理器 管理手机里面活动信息,动态的内容
	public static int getRunningProcessCount(Context context){
		
		ActivityManager am=(ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
		List<RunningAppProcessInfo> infos=am.getRunningAppProcesses();
		return infos.size();
		
	}
	/*
	 * 得到系统的可用内存
	 */
	
	public static long getAvailMem(Context context){
		ActivityManager am=(ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
	    MemoryInfo outInfo=new MemoryInfo();
	    am.getMemoryInfo(outInfo);
		return outInfo.availMem;
	}
	
	
	/*
	 * 得到系统的全部内存
	 */
	
	public static long getTotalMem(Context context){
	/*只能在4.0及以上版本可用
		ActivityManager am=(ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
	    MemoryInfo outInfo=new MemoryInfo();
	    am.getMemoryInfo(outInfo);
		return outInfo.totalMem;
	*/
		
		try {
			File file=new File("/proc/meminfo");
			FileInputStream fis=new FileInputStream(file);
			BufferedReader br=new BufferedReader(new InputStreamReader(fis));
			String line=br.readLine();
			
			StringBuilder sb=new StringBuilder();
			for(char c:line.toCharArray()){
				if(c>='0'&&c<='9'){
					sb.append(c);
				}
			}
			return Long.parseLong(sb.toString())*1024;
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return 0;
		}
	
	}
	
	
	
}

   源码下载地址:http://download.csdn.net/detail/itjavawfc/8370423

你可能感兴趣的:(金山手机卫士进程清理)