在android下PackageManager相当windows下的程序管理器
1.得到PackageManager包管理器
PackageManager pm = getContext().getPackageManager();
2.在这个包管理器下有获取标题,获取图标,获取版本号,getInstalledApplications(int flags); 这方法是返回所有的应用程序信息返回List<ApplicationInfo>,
List<PackageInfo> packageInfos = pm.getInstalledPackages(flags);//这里的flags传的是范围,如果传一个PackageManger.GET_UNINSTALLED_PACKAGES那么会把那么卸载的但没有清除数据的应用程序给返回回来.
3.遍历信息获取PackageInfo
○ packageinfo就相当于一个程序配置清单,可以获取里的配置信息,如果想获取<manifest>结点里的信息直接调用方法就可以,如果想获取<application>结点里面的方法就需要使用packinfo.applicationInfo()这个方法就可以得到<application>结点,然后就可以获取里面的信息了,返回值是ApplicationInfo对象,在这个对象里面有获取应用程序图标,名称,包等方法.
○ 在Applicationinfo对象中还有一个loadIcon(PackageManger pm)这个可以得到这个应用程序的图标,返回的是一个Drawable类型
○ Drawable appicon = appinfo.loadIcon(pm);
○ String name = appinfo.loadLabel(pm).toString()返回应用程序的名称
○ packinfo.packageName;获取包名,packinfo.versionName;获取版本信息
4.判断是用户程序还是系统程序,这个可以搜查系统源代码的setting代码,查看已下载,然后查看里面的代码是如果判断的
5.获取<uses-permission>结点的权限信息
在创建PackageInfo时指定他解析权限信息,因为android在设置时默认是不解析权限信息,只解析图标,名称,包等信息,所以修改上面创建Packinfos的代码
List<PackageInfo> packageInfos = pm.getInstalledPackages(PackageManger.GET_UNINSTALLED_PACKAGES|PackageManger.GET_PERMISSIONS);
然后就可以调用appinfo.requestedPermissions;获取权限的数组,然后就可遍历判断了
因为listView在使用历吏缓存view对象时要避免使用历史缓存的view里面的一部分布局是可变的,不是每个view都有的,那么我们就要使用holder.ll.removeAllViews()的方法去清除这个布局中一个布局的的缓存view,因为这部分缓冲不是每个view都是需要的
在一个listView中如何分别显示用户应用跟系统应用
需要多显示出来两个条目,分别显示是用户程序还是系统程序
1.在继承BaseAdapter的适配器类就要更改了,显示数据要加上2,因为要加两个条目
2.因为需要显示用户跟系统的程序,所以要在获取所以的程序后进行判断,然后分别存在用户集合跟系统集合中
3.因为有了系统跟用户的集合那么我们定义适配器时计算长度可以使用用户集合数量+1+系统集合数量+1
4.然后在getIView方法中就要进行判断了,因为要显示两种不同的view
判断如果位置=0那么创建一个TextView用来显示用户程序的标签,
如果位置<=用户集合的数量那么就显示用户的程序,
如果位置等用户集合的数量+1那么我们就又要显示一个TextView对象显示系统程序文本
如果位置大于用户集合的数量+1小于总集合那么就显示系统条目,不过条目的位置要注意,不是直接position,而是position-用户的集合-2,因为我们要根据position去取系统集合里的数据
注意上面的应用程序显示是没有问题的但是拖动的时候会有问题,因为我们使用了历史缓存数据但是一个是textView,而另一个是我们填充的view对象,这两个对象不一致,所以我们在适配器类中还要判断他的类型,如果历史缓冲对象为空或者是TextView对象(converView == null || converView instanceof Textview)那么我们就得新创建一个对象不使用缓存对象
采用异步任务执行耗时的操作:
一般我们要在一个线程中发送一个信息给handleMessage,然后更新UI,google也帮我们封装了这个操作,AsyncTask<Params,Progress,Result>
Params:执行线程时传进来的参数,如果不关心的话可以传一个void,
Progress:可以发布进度如果不关心可以传一个void
Result:任务执行完返回的值,不关心可以传一个void,这个是doInBackground()方法返回的值
复写里面三个方法:
doInBackground();//运行在子线程里面的方法,可以进行耗时的操作
onPreExceute();//在开启异步任务后,执行异步任务之前调用的方法,运行在主线程(UI),因为在主线程所以可以调用toast
onPostExecute()//执行异步任务之后调用的方法,运行在主线程(UI),参数是doInBackground()返回回来的数据
onProgressUpdate()这个方法可以装进度发布出去,这个执行要求在new AsyncTask时要将发布进度可以将参数void改成Integer
然后调用task.execute()//执行异步任务
用异步更新进度
1.复写onProgressUpdate(Integer… value){
pd.setProgress(value[0]);
}//这个方法是用publishProgress()这个方法去激活的
2.在外面创建一个进度条
private ProgressDialog pd;
3.在复写的onPreExecute()的方法中初始化进度条
pd = new ProgressDialog(AsyncTaskActivity.this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setTitle("标题");
pd.setMax(100);
pd.show();
4.在doInBackground()方法中更新进度,可以用循环去更新进度
publishProgress(value);//发布进度,然后onProgressUpdate()这个方法会接收到
5.在onPostExecute()这个方法结束进度条pd.dismiss();
如果只要一个线程那么就不用异步操作了,因为异步为开启一个线程池,会消耗内存