warning

android多进程应用在前台后台服务会被回收吗_包名

真机运行的时候,会有一些系统的核心进程时无法获取到的,他只有一个包名,没有manifest里的icon、activity什么的,用包名去获取时没有内容的

所以获取不到的时候会报上面的问题

android多进程应用在前台后台服务会被回收吗_包名_02

在工具类的异常处理里,把包名拿到就好

} catch (NameNotFoundException e) {				
				e.printStackTrace();
				//一些无法显示的核心经常的包名显示出来
				ProcessInfo pinfo = new ProcessInfo(packagename, null, is_user, memory_usage, packagename);			
				processinfos.add(pinfo);
			}



显示不同进程类别的框框

refreshData();
		
        lv_procmanage_procinfolist.setOnScrollListener(new OnScrollListener() {		
			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				// TODO Auto-generated method stub
				
			}			
			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				// TODO Auto-generated method stub				
				if (firstVisibleItem>user_proinfolist.size()+1) {
					tv_procmanage_class.setText("系统进程("+sys_proinfolist.size()+")个");				
			    }
				else {
					tv_procmanage_class.setText("用户进程("+user_proinfolist.size()+")个");				
				}
			}
		});



checkbox的勾选状态的问题,在滑动之后,划出去的若勾选了,由于convert的作用,也给了划进来的item勾上了

故而需要一个判断,在bean里需要一个ischecked,并且一开始就给他一个false的初值,工具类里也要获取这个状态

之前已经都写好了,这里不单独列出来了


然后划回来,勾选的没有了,因为是根据info获取的,而之前设置了默认为false

需要一个itemlistener

注意一些细节,滑出滑进,父控件与checkbox自己的点击问题,刷UI

lv_procmanage_procinfolist.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// TODO Auto-generated method stub			
				ProcessInfo procInfo;
				if (position< user_proinfolist.size()+1) {
					procInfo = user_proinfolist.get(position-1);
				}else {
					procInfo = sys_proinfolist.get(position-user_proinfolist.size()-2);
				}				
				
				if ("com.rjl.mobilephonemanager".equals(procInfo.getPackagename())) {
					return;
				}			
				//当前没被勾选,点击后应为true,记住了,方便滑进滑出
				//layout里的checkbox要设为false,这样只能点击父控件
				if (!procInfo.isIschecked()) {
					procInfo.setIschecked(true);
				}else {
					procInfo.setIschecked(false);
				}
				//点击后要刷新下,负责只是改了数据而UI不变
				if (adapter!=null) {
					adapter.notifyDataSetChanged();
				}			
			}
		});




完成业务逻辑,清理进程

先有4个button

这里有一个属性 layout_weight 若后面直接跟一个数字,则表示渲染优先级,越大优先级越低,所以这里先显示了下面的linearlayout,他们的button都用了包裹内容

而上面的帧布局后显示。这样子不用去把权重写死,写死权重有时候未必合适

<pre name="code" class="html"><FrameLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1000">
    <ListView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/lv_procmanage_procinfolist">
    </ListView>
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#798091"
        android:textColor="#FFFFFF"
        android:textSize="15sp"
        android:id="@+id/tv_procmanage_class"/>
    </FrameLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="全选"
            android:layout_marginBottom="2dp"
            android:onClick="selectall"/>
         <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="取消"
             android:layout_marginBottom="2dp"
             android:onClick="cancle"/>
         <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="清理"
            android:layout_marginBottom="2dp"
            android:onClick="kill" /> 
            <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="设置"
            android:layout_marginBottom="2dp"
            android:onClick="setting"/>       
    </LinearLayout>

对比另一种写法

<FrameLayout 
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="5">



<LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:layout_weight="1">



上面写法,会先显示帧布局



public void selectall(View v){
    	
    }
    public void cancle(View v){
    	
    }     
    public void kill(View v){
    	
    }    
    public void setting(View v){
    
    }



全选

public void selectall(View v){
    	for(ProcessInfo p : user_proinfolist){
    		if ("com.rjl.mobilephonemanager".equals(p.getPackagename())) {
				continue;
			}
    		p.setIschecked(true); 
    	}
    	for(ProcessInfo p : sys_proinfolist){
    		p.setIschecked(true); 
    	}
    	//刷UI
    	if (adapter!=null) {
			adapter.notifyDataSetChanged();
		}
    }



取消

public void cancle(View v){
    	for(ProcessInfo p : user_proinfolist){       	
    		p.setIschecked(false); 
    	}
    	for(ProcessInfo p : sys_proinfolist){
    		p.setIschecked(false); 
    	}
    	
    	if (adapter!=null) {
			adapter.notifyDataSetChanged();
		}
    }



设置

public void setting(View v){
    	if (show_sysproc) {
			show_sysproc=false;
		}
    	else {
			show_sysproc=true;
		}
    	if (adapter!=null) {
			adapter.notifyDataSetChanged();
		}   	
    }




大头戏  清理进程 后台进程,需要权限

killBackgroundProcesses方法
public void kill(View v){
    	ActivityManager ams = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    	
    	for(ProcessInfo p : user_proinfolist){
        	
    		if (p.isIschecked()) {
    	    	ams.killBackgroundProcesses(p.getPackagename());
                user_proinfolist.remove(p);
			}
     	}
    	for(ProcessInfo p : sys_proinfolist){
    		if (p.isIschecked()) {
    	    	ams.killBackgroundProcesses(p.getPackagename());
    	    	sys_proinfolist.remove(p);
			}    	
    	}
    	//干掉后台进程(前台 可见 服务 后台 空)
    	if (adapter!=null) {
			adapter.notifyDataSetChanged();
		}  
    }



但是有问题,不能一边遍历一边删除其中的元素

把删除的方法单独列出来

public void kill(View v){
    	ActivityManager ams = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    	//遍历完了再更改,记录一下
    	List<ProcessInfo> deletedProc = new ArrayList<ProcessInfo>();
    	for(ProcessInfo p : user_proinfolist){
        	
    		if (p.isIschecked()) {
    	    	ams.killBackgroundProcesses(p.getPackagename());
                /*user_proinfolist.remove(p);*/ //不能一边遍历一边删除元素
			}
     	}
    	for(ProcessInfo p : sys_proinfolist){
    		if (p.isIschecked()) {
    	    	ams.killBackgroundProcesses(p.getPackagename());
    	    	/*sys_proinfolist.remove(p);*/
			}    	
    	}
    	//不能直接对线程的列表边遍历边删除
    	//删完记录下来,再去把两个数据源改掉,改完再刷UI
    	for(ProcessInfo proc : deletedProc){
    		if (proc.isIs_user()) {
    			user_proinfolist.remove(proc);		
			}
    		else {
				sys_proinfolist.remove(proc);
			}
    	}
    	//干掉后台进程(前台 可见 服务 后台 空)
    	if (adapter!=null) {
			adapter.notifyDataSetChanged();
		}  
    }



这时候有一个bug,全选后再删除,会挂掉

全选后会全部记录在节点里,然后全部删除,这个时候sys_proinfolist里就没东西,然后adapter要getView,他要根据sys_proinfolist里的位置来操作(position+2),现在是空的,故而有问题报错

@Override
		public int getCount() {
			// TODO Auto-generated method stub
			if (show_sysproc) {
				listcount = processinfolist.size()+2;				 
			}else {
				listcount= user_proinfolist.size()+1;
			}
			//显示的是总数减掉我们点击的要清除掉的线程数
			<span style="color:#ff0000;">return listcount-deletecount;</span>			
		}



for(ProcessInfo proc : deletedProc){
    		if (proc.isIs_user()) {
    			user_proinfolist.remove(proc);		
			}
    		else {
				sys_proinfolist.remove(proc);
			}
    	}
    	//要删除的个数
    	<span style="color:#ff0000;">deletecount = deletedProc.size();</span>
    	//干掉后台进程(前台 可见 服务 后台 空)
    	if (adapter!=null) {
			adapter.notifyDataSetChanged();



动态显示删除后的进程数

先要有原有的进程数

//获得原有进程数
    	int old_count = user_proinfolist.size()+sys_proinfolist.size();
    	for(ProcessInfo p : user_proinfolist){



//要删除的个数
    	deletecount = deletedProc.size();
    	//当前进程数
    	tv_processmanage_num.setText("当前手机进程数为\n"+(old_count-deletecount));



进程清理后,内存也要变

//初始化初始空闲空间
    	int free_memory = 0;
    	for(ProcessInfo p : user_proinfolist){



for(ProcessInfo proc : deletedProc){
    		if (proc.isIs_user()) {
    			user_proinfolist.remove(proc);	   			
			}
    		else {
				sys_proinfolist.remove(proc);
			}
    		<span style="color:#ff0000;">free_memory += proc.getMemory_usage();</span>
    	}



这里统计并不十分精确,因为系统存在共享的情况