标签:des android style http io color ar os sp
其实清除缓存是有两种的,一种是清除手机rom里面的缓存,一种是清除手机sd卡里面的缓存,我们今天主要讲的就是第一种
ps:这里来一个知识扫盲,就是手机里面的rom和ram啦,如果已经知道了的,就可以跳过啦,我们去买手机,有时候经常会被那些销售人员忽悠的,说什么8G的内存啦,什么的,其实他这里面说的极大可能就是你手机里面rom的大小啦,rom就是read only menory(只读存储器)你可以把它当成你电脑上的硬盘,不过它只能读取而已,ram就是random access menory(随机存取器)这个就相当于你电脑的内存啦,所以那个销售人员说的手机内存有多大的时候,我们一定要问清楚啦,不要被人蒙了
好啦,回归正题,我们今天讲的那个缓存是清除手机rom里面的缓存,其实也是挺简单的,只要知道了要怎么做之后,至于那个清除sd卡里面的缓存的话,这个我到时会给大家说一下是怎样清理的,具体我就不写了,好,先来看一下我们要做的效果
上的第一个图就是我们把我们的应用的一些信息给读取出来了,但那个界面不怎么好看,大家可以自己优化一下,当我们点击了要清理缓存的条目时,我们就会进入到系统设置里面的一个界面,因为清理rom里面的缓存是要root才行的,而我们没有root,那么就只要借助系统里面的功能啦,到时我也会教大家怎样root手机的
好啦,废话不多说,我们直接进入代码阶段
首先,我们先新建一个model类用来存放缓存的信息
com.xiaobin.security.domain.CacheInfo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package
com.xiaobin.security.domain; import
android.graphics.drawable.Drawable; public
class
CacheInfo { private
String name; private
String packageName; private
Drawable icon; //应用大小 private
String codeSize; //数据大小 private
String dataSize; //缓存大小 private
String cacheSize; public
String getName() { return
name; } public
void
setName(String name) { this .name
= name; } public
String getPackageName() { return
packageName; } public
void
setPackageName(String packageName) { this .packageName
= packageName; } public
Drawable getIcon() { return
icon; } public
void
setIcon(Drawable icon) { this .icon
= icon; } public
String getCodeSize() { return
codeSize; } public
void
setCodeSize(String codeSize) { this .codeSize
= codeSize; } public
String getDataSize() { return
dataSize; } public
void
setDataSize(String dataSize) { this .dataSize
= dataSize; } public
String getCacheSize() { return
cacheSize; } public
void
setCacheSize(String cacheSize) { this .cacheSize
= cacheSize; } } |
那么,怎样去读取这些信息呢,其实PackageManagerj里面有一个私有的方法的,叫getPackageSizeInfo,
所以现在思路清楚啦,我们就是要通过反射来调用这个方法,然后,getPackageSizeInfo这个方法要传递一个IPackageStatsObserver.Stub对象的,这个对象我们一看,就知道是一个AIDL的对象啦,所以,我们就要把相应的AIDL文件给放到src目录下面啦,我们就是在它里面拿到缓存大小,这 些数据的啦,
好啦,说得有点玄,直接上代码更清晰
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
/** *
通过AIDL的方法来获取到应用的缓存信息,getPackageSizeInfo是PackageManager里面的一个私有方法来的 *
我们通过反射就可以调用到它的了,但是这个方法里面会传递一个IPackageStatsObserver.Stub的对象 *
里面就可能通过AIDL来获取我们想要的信息了 *
*
因为这样的调用是异步的,所以当我们完成获取完这些信息之后,我们就通过handler来发送一个消息 *
来通知我们的应用,通过getCacheInfos来获取到我们的Vector *
*
为什么要用Vector呢,因为下面的方法是异步的,也就是有可能是多线程操作,所以我们就用了线程安全的Vector *
*
@param cacheInfo *
@param position */ private
void
initDataSize( final
CacheInfo cacheInfo, final
int
position) { try { Method
method = PackageManager. class .getMethod( "getPackageSizeInfo" ,
new
Class[] { String. class , IPackageStatsObserver. class
}); method.invoke(packageManager, new
Object[] { cacheInfo.getPackageName(), new
IPackageStatsObserver.Stub() { @Override public
void
onGetStatsCompleted( PackageStats
pStats, boolean
succeeded) throws
RemoteException { System.out.println( "onGetStatsCompleted"
+ position); long
cacheSize = pStats.cacheSize; long
codeSize = pStats.codeSize; long
dataSize = pStats.dataSize; cacheInfo.setCacheSize(TextFormater .dataSizeFormat(cacheSize)); cacheInfo.setCodeSize(TextFormater .dataSizeFormat(codeSize)); cacheInfo.setDataSize(TextFormater .dataSizeFormat(dataSize)); cacheInfos.add(cacheInfo); if
(position == (size - 1 )) { //
当完全获取完信息之后,发送一个成功的消息 //
1对应的就是CacheClearActivity里面的FINISH handler.sendEmptyMessage( 1 ); } } }
}); } catch
(Exception e) { e.printStackTrace(); } } |
好啦,下面我们把完整的类粘出来,这个类写得有点复杂,主要是因为获取缓存大小这些信息的内部实现是异步的,我们要保证数据的正确性,所以可能就写得有点难理解
大家如果看不懂这个类的话,就欢迎留言
com.xiaobin.security.engine.CacheInfoProvider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
package
com.xiaobin.security.engine; import
java.lang.reflect.Method; import
java.util.List; import
java.util.Vector; import
android.content.Context; import
android.content.pm.ApplicationInfo; import
android.content.pm.IPackageStatsObserver; import
android.content.pm.PackageInfo; import
android.content.pm.PackageManager; import
android.content.pm.PackageStats; import
android.graphics.drawable.Drawable; import
android.os.Handler; import
android.os.RemoteException; import
com.xiaobin.security.domain.CacheInfo; import
com.xiaobin.security.utils.TextFormater; public
class
CacheInfoProvider { private
Handler handler; private
PackageManager packageManager; private
Vector<cacheinfo> cacheInfos; private
int
size = 0 ; public
CacheInfoProvider(Handler handler, Context context) { //
拿到一个包管理器 packageManager
= context.getPackageManager(); this .handler
= handler; cacheInfos
= new
Vector<cacheinfo>(); } public
void
initCacheInfos() { //
获取到所有安装了的应用程序的信息,包括那些卸载了的,但没有清除数据的应用程序 List<packageinfo>
packageInfos = packageManager .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES); size
= packageInfos.size(); for
( int
i = 0 ;
i < size; i++) { PackageInfo
packageInfo = packageInfos.get(i); CacheInfo
cacheInfo = new
CacheInfo(); //
拿到包名 String
packageName = packageInfo.packageName; cacheInfo.setPackageName(packageName); //
拿到应用程序的信息 ApplicationInfo
applicationInfo = packageInfo.applicationInfo; //
拿到应用程序的程序名 String
name = applicationInfo.loadLabel(packageManager).toString(); cacheInfo.setName(name); //
拿到应用程序的图标 Drawable
icon = applicationInfo.loadIcon(packageManager); cacheInfo.setIcon(icon); initDataSize(cacheInfo,
i); } } /** *
通过AIDL的方法来获取到应用的缓存信息,getPackageSizeInfo是PackageManager里面的一个私有方法来的 *
我们通过反射就可以调用到它的了,但是这个方法里面会传递一个IPackageStatsObserver.Stub的对象 *
里面就可能通过AIDL来获取我们想要的信息了 *
*
因为这样的调用是异步的,所以当我们完成获取完这些信息之后,我们就通过handler来发送一个消息 *
来通知我们的应用,通过getCacheInfos来获取到我们的Vector *
*
为什么要用Vector呢,因为下面的方法是异步的,也就是有可能是多线程操作,所以我们就用了线程安全的Vector *
*
@param cacheInfo *
@param position */ private
void
initDataSize( final
CacheInfo cacheInfo, final
int
position) { try { Method
method = PackageManager. class .getMethod( "getPackageSizeInfo" ,
new
Class[] { String. class , IPackageStatsObserver. class
}); method.invoke(packageManager, new
Object[] { cacheInfo.getPackageName(), new
IPackageStatsObserver.Stub() { @Override public
void
onGetStatsCompleted( PackageStats
pStats, boolean
succeeded) throws
RemoteException { System.out.println( "onGetStatsCompleted"
+ position); long
cacheSize = pStats.cacheSize; long
codeSize = pStats.codeSize; long
dataSize = pStats.dataSize; cacheInfo.setCacheSize(TextFormater .dataSizeFormat(cacheSize)); cacheInfo.setCodeSize(TextFormater .dataSizeFormat(codeSize)); cacheInfo.setDataSize(TextFormater .dataSizeFormat(dataSize)); cacheInfos.add(cacheInfo); if
(position == (size - 1 )) { //
当完全获取完信息之后,发送一个成功的消息 //
1对应的就是CacheClearActivity里面的FINISH handler.sendEmptyMessage( 1 ); } } }
}); } catch
(Exception e) { e.printStackTrace(); } } public
Vector<cacheinfo> getCacheInfos() { return
cacheInfos; } public
void
setCacheInfos(Vector<cacheinfo> cacheInfos) { this .cacheInfos
= cacheInfos; } } </cacheinfo></cacheinfo></packageinfo></cacheinfo></cacheinfo> |
上面我已经说过了,如果我们要自己删除rom的缓存的话,那就是要root权限的,但我们现在没有,所以,我们就要通过系统设置里面的一个功能来进行清除啦
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/** *
Android2.3打开settings里面的那个应用的详细界面 *
后来我又查了一个Android4.1的,也是这样写的,所有应该是2.3之后,都是这样写的了, *
但是这只是猜测,各位有空的可以去下载Android Settings的代码看一下 *
这样就可以做成多个版本的适配了 *
<intent-filter> *
*
<category android:name="android.intent.category.DEFAULT"> *
<data android:scheme="package"> *
</data></category></action></intent-filter> */ /** *
Android2.2打开settings里面的那个应用的详细界面 *
用这个版本来打开的话,就要加多一句把包名设置进去的 *
intent.putExtra("pkg", packageName); *
<intent-filter> *
*
<category android:name="android.intent.category.DEFAULT"> *
<category android:name="android.intent.category.VOICE_LAUNCH"> *
</category></category></action></intent-filter> */ Intent
intent = new
Intent(); intent.setAction( "android.settings.APPLICATION_DETAILS_SETTINGS" ); intent.addCategory( "android.intent.category.DEFAULT" ); intent.setData(Uri.parse( "package:"
+ cacheInfos.get(position).getPackageName())); startActivity(intent); |
下面是完整的activity代码,布局文件就不放啦,因为写得太难看了
com.xiaobin.security.ui.CacheClearActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
package
com.xiaobin.security.ui; import
java.util.Vector; import
android.annotation.SuppressLint; import
android.app.ListActivity; import
android.content.Intent; import
android.net.Uri; import
android.os.Bundle; import
android.os.Handler; import
android.os.Message; import
android.view.View; import
android.view.ViewGroup; import
android.view.Window; import
android.widget.AdapterView; import
android.widget.AdapterView.OnItemClickListener; import
android.widget.BaseAdapter; import
android.widget.ImageView; import
android.widget.LinearLayout; import
android.widget.ListView; import
android.widget.TextView; import
com.xiaobin.security.R; import
com.xiaobin.security.domain.CacheInfo; import
com.xiaobin.security.engine.CacheInfoProvider; public
class
CacheClearActivity extends
ListActivity { private
static
final
int
LOADING = 0 ; private
static
final
int
FINISH = 1 ; private
CacheInfoProvider provider; private
ListView lv_list; private
LinearLayout ll_load; private
Vector<cacheinfo> cacheInfos; @SuppressLint ( "HandlerLeak" ) private
Handler handler = new
Handler() { public
void
handleMessage(Message msg) { switch
(msg.what) { case
LOADING: ll_load.setVisibility(View.VISIBLE); break ; case
FINISH: ll_load.setVisibility(View.INVISIBLE); //
当加载完成之后,就调用provider里面的get方法, //
这样就可以得到一个加载完成后的数据了 cacheInfos
= provider.getCacheInfos(); lv_list.setAdapter( new
CacheAdapter()); break ; default : break ; } } }; @Override protected
void
onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.cache_clear); provider
= new
CacheInfoProvider(handler, this ); lv_list
= getListView(); ll_load
= (LinearLayout) findViewById(R.id.ll_cache_clear_load); lv_list.setOnItemClickListener( new
OnItemClickListener() { @Override public
void
onItemClick(AdapterView<!--?--> parent, View view, int
position, long
id) { /** *
Android2.3打开settings里面的那个应用的详细界面 *
后来我又查了一个Android4.1的,也是这样写的,所有应该是2.3之后,都是这样写的了, *
但是这只是猜测,各位有空的可以去下载Android Settings的代码看一下 *
这样就可以做成多个版本的适配了 *
<intent-filter> *
*
<category android:name="android.intent.category.DEFAULT"> *
<data android:scheme="package"> *
</data></category></action></intent-filter> */ /** *
Android2.2打开settings里面的那个应用的详细界面 *
用这个版本来打开的话,就要加多一句把包名设置进去的 *
intent.putExtra("pkg", packageName); *
<intent-filter> *
*
<category android:name="android.intent.category.DEFAULT"> *
<category android:name="android.intent.category.VOICE_LAUNCH"> *
</category></category></action></intent-filter> */ Intent
intent = new
Intent(); intent.setAction( "android.settings.APPLICATION_DETAILS_SETTINGS" ); intent.addCategory( "android.intent.category.DEFAULT" ); intent.setData(Uri.parse( "package:"
+ cacheInfos.get(position).getPackageName())); startActivity(intent); } }); loadData(); } private
void
loadData() { ll_load.setVisibility(View.VISIBLE); new
Thread( new
Runnable() { @Override public
void
run() { provider.initCacheInfos(); } }).start(); } //
======================================================================= private
class
CacheAdapter extends
BaseAdapter { @Override public
int
getCount() { return
cacheInfos.size(); } @Override public
Object getItem( int
position) { return
cacheInfos.get(position); } @Override public
long
getItemId( int
position) { return
position; } @Override public
View getView( int
position, View convertView, ViewGroup parent) { View
view; ViewHolder
holder; CacheInfo
info = cacheInfos.get(position); if
(convertView == null ) { view
= View.inflate(CacheClearActivity. this , R.layout.cache_clear_item,
null ); holder
= new
ViewHolder(); holder.iv_icon
= (ImageView) view .findViewById(R.id.iv_cache_icon); holder.tv_name
= (TextView) view .findViewById(R.id.tv_cache_name); holder.tv_code
= (TextView) view .findViewById(R.id.tv_cache_code); holder.tv_data
= (TextView) view .findViewById(R.id.tv_cache_data); holder.tv_cache
= (TextView) view .findViewById(R.id.tv_cache_cache); view.setTag(holder); } else { view
= convertView; holder
= (ViewHolder) view.getTag(); } holder.iv_icon.setImageDrawable(info.getIcon()); holder.tv_name.setText(info.getName()); holder.tv_code.setText( "应用大小:"
+ info.getCodeSize()); holder.tv_data.setText( "数据大小:"
+ info.getDataSize()); holder.tv_cache.setText( "缓存大小:"
+ info.getCacheSize()); return
view; } } private
class
ViewHolder { ImageView
iv_icon; TextView
tv_name; TextView
tv_cache; TextView
tv_code; TextView
tv_data; } } </cacheinfo> |
大家都知道,我们装的大部分应用,都会有sd卡里面建一个目录,然后装一些应用的信息的,而这些,就是这些应用对应存放缓存的目录啦,
要清除sd卡里面的缓存,其实就是要有一个数据库啦,它专门收录市面上一些常用的应用,在sd卡上建立的目录名称,然后再通过这个数据库,然后对sd卡里面的目录清除的而已,这个方法是比较的麻烦的,还要有数据库的支持才行,所以大家可以自己试试
标签:des android style http io color ar os sp
原文地址:http://blog.csdn.net/love_xsq/article/details/41078463