Skip to content

Commit d98abb3

Browse files
committed
添加缓存计算,清理
添加缓存计算,清理
1 parent e803264 commit d98abb3

File tree

7 files changed

+279
-5
lines changed

7 files changed

+279
-5
lines changed

android/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
3131
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
3232

33+
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
34+
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>
35+
3336
<application>
3437
<!-- 声明网易云通信后台服务,如需保持后台推送,使用独立进程效果会更好。 -->
3538
<service
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
**
3+
** Copyright 2007, The Android Open Source Project
4+
**
5+
** Licensed under the Apache License, Version 2.0 (the "License");
6+
** you may not use this file except in compliance with the License.
7+
** You may obtain a copy of the License at
8+
**
9+
** http://www.apache.org/licenses/LICENSE-2.0
10+
**
11+
** Unless required by applicable law or agreed to in writing, software
12+
** distributed under the License is distributed on an "AS IS" BASIS,
13+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
** See the License for the specific language governing permissions and
15+
** limitations under the License.
16+
*/
17+
18+
package android.content.pm;
19+
20+
/**
21+
* API for package data change related callbacks from the Package Manager.
22+
* Some usage scenarios include deletion of cache directory, generate
23+
* statistics related to code, data, cache usage(TODO)
24+
*/
25+
oneway interface IPackageDataObserver {
26+
void onRemoveCompleted(in String packageName, boolean succeeded);
27+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package android.content.pm;
2+
3+
import android.content.pm.PackageStats;
4+
/**
5+
* API for package data change related callbacks from the Package Manager.
6+
* Some usage scenarios include deletion of cache directory, generate
7+
* statistics related to code, data, cache usage(TODO)
8+
*/
9+
oneway interface IPackageStatsObserver {
10+
11+
void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);
12+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package android.content.pm;
2+
3+
parcelable PackageStats;
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
package com.netease.im;
2+
3+
import android.content.Context;
4+
import android.content.pm.IPackageDataObserver;
5+
import android.content.pm.IPackageStatsObserver;
6+
import android.content.pm.PackageManager;
7+
import android.content.pm.PackageStats;
8+
import android.os.AsyncTask;
9+
import android.os.Build;
10+
import android.os.Environment;
11+
import android.os.RemoteException;
12+
import android.os.StatFs;
13+
14+
import com.netease.im.uikit.common.util.file.FileUtil;
15+
import com.netease.im.uikit.common.util.log.LogUtil;
16+
import com.netease.im.uikit.common.util.storage.StorageType;
17+
import com.netease.im.uikit.common.util.storage.StorageUtil;
18+
import com.netease.nimlib.sdk.NIMClient;
19+
import com.netease.nimlib.sdk.msg.MsgService;
20+
import com.netease.nimlib.sdk.msg.model.RecentContact;
21+
22+
import java.io.File;
23+
import java.lang.reflect.Method;
24+
import java.util.HashSet;
25+
import java.util.List;
26+
import java.util.Set;
27+
28+
/**
29+
* Created by dowin on 2017/7/6.
30+
* <p>
31+
* log: SDK日志
32+
* file: 文件消息文件
33+
* image: 图片消息文件
34+
* audio:语音消息文件
35+
* video:视频消息文件
36+
* thumb:图片/视频缩略图文件
37+
*/
38+
39+
public class FileCacheUtil {
40+
41+
final static String TAG = "FileCacheUtil";
42+
43+
public static void getCacheSie() {
44+
45+
new AsyncTask<Void, Void, Void>() {
46+
47+
@Override
48+
protected Void doInBackground(Void... params) {
49+
Set<String> pathList = getCacheDir();
50+
long allLength = 0;
51+
for (String s : pathList) {
52+
long t = makeDirSize(new File(s));
53+
LogUtil.i(TAG, s + ":" + FileUtil.formatFileSize(t));
54+
allLength += t;
55+
}
56+
LogUtil.i(TAG, "allFile" + ":" + FileUtil.formatFileSize(allLength));
57+
final long finalAllLength = allLength;
58+
getCacheSize(new IPackageStatsObserver.Stub() {
59+
@Override
60+
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {
61+
62+
LogUtil.i(TAG, "cacheSize" + ":" + FileUtil.formatFileSize(pStats.cacheSize));
63+
LogUtil.i(TAG, "externalCacheSize" + ":" + FileUtil.formatFileSize(pStats.externalCacheSize));
64+
65+
// LogUtil.i(TAG, "codeSize" + ":" + FileUtil.formatFileSize(pStats.codeSize));
66+
// LogUtil.i(TAG, "dataSize" + ":" + FileUtil.formatFileSize(pStats.dataSize));
67+
// LogUtil.i(TAG, "externalCodeSize" + ":" + FileUtil.formatFileSize(pStats.externalCodeSize));
68+
// LogUtil.i(TAG, "externalDataSize" + ":" + FileUtil.formatFileSize(pStats.externalDataSize));
69+
// LogUtil.i(TAG, "externalMediaSize" + ":" + FileUtil.formatFileSize(pStats.externalMediaSize));
70+
// LogUtil.i(TAG, "externalObbSize" + ":" + FileUtil.formatFileSize(pStats.externalObbSize));
71+
long result = finalAllLength;
72+
result += pStats.cacheSize;
73+
result += pStats.cacheSize;
74+
LogUtil.i(TAG, "result" + ":" + FileUtil.formatFileSize(result));
75+
}
76+
});
77+
return null;
78+
}
79+
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
80+
}
81+
82+
public static void clearCache() {
83+
new AsyncTask<Void, Void, Void>() {
84+
85+
@Override
86+
protected Void doInBackground(Void... params) {
87+
// IMApplication.getImageLoaderKit().clearCache();
88+
Set<String> pathList = getCacheDir();
89+
for (String s : pathList) {
90+
// deleteDir(new File(s));
91+
}
92+
List<RecentContact> recentContacts = NIMClient.getService(MsgService.class).queryRecentContactsBlock();
93+
if (recentContacts != null && !recentContacts.isEmpty()) {
94+
// NIMClient.getService(MsgService.class).clearMsgDatabase(true);
95+
}
96+
freeStorageAndNotify(new IPackageDataObserver.Stub() {
97+
98+
@Override
99+
public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
100+
LogUtil.i(TAG, "result" + ":" + packageName);
101+
LogUtil.i(TAG, "result" + ":" + succeeded);
102+
}
103+
});
104+
return null;
105+
}
106+
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
107+
}
108+
109+
static void deleteDir(File file) {
110+
if (file == null || !file.exists()) {
111+
return;
112+
}
113+
if (file.isFile()) {
114+
file.delete();
115+
}
116+
File[] list = file.listFiles();
117+
if (list != null && list.length > 0) {
118+
for (File f : list) {
119+
if (f.isDirectory()) {
120+
deleteDir(f);
121+
} else {
122+
f.delete();
123+
}
124+
}
125+
}
126+
}
127+
128+
static long makeDirSize(File file) {
129+
130+
if (file == null || !file.exists()) {
131+
return 0L;
132+
}
133+
if (file.isFile()) {
134+
return file.length();
135+
}
136+
long all = 0L;
137+
File[] list = file.listFiles();
138+
if (list != null && list.length > 0) {
139+
for (File f : list) {
140+
if (f.isDirectory()) {
141+
all += makeDirSize(f);
142+
} else {
143+
all += f.length();
144+
}
145+
}
146+
}
147+
return all;
148+
}
149+
150+
static void getCacheSize(IPackageStatsObserver.Stub observer) {
151+
Context context = IMApplication.getContext();
152+
String pkg = context.getPackageName();
153+
PackageManager pm = context.getPackageManager();
154+
try {
155+
LogUtil.i(TAG, "name:" + pm.getClass().getName());
156+
Method getPackageSizeInfo = pm.getClass().getMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class);
157+
getPackageSizeInfo.invoke(pm, pkg, observer);
158+
} catch (Exception ex) {
159+
LogUtil.e("", "NoSuchMethodException");
160+
ex.printStackTrace();
161+
}
162+
}
163+
164+
private static Set<String> getCacheDir() {
165+
166+
StorageType[] storageTypes = StorageType.values();
167+
String[] sdkFileName = {"log/", "file/", "image/", "audio/", "video/", "thumb/"};
168+
Set<String> path = new HashSet<>();
169+
for (StorageType type : storageTypes) {
170+
path.add(StorageUtil.getDirectoryByDirType(type));
171+
}
172+
for (String sdk : sdkFileName) {
173+
path.add(IMApplication.getSdkStorageRooPath() + "/" + sdk);
174+
}
175+
File imageCacheDir = IMApplication.getImageLoaderKit().getChacheDir();
176+
if (imageCacheDir.exists()) {
177+
path.add(imageCacheDir.getAbsolutePath());
178+
}
179+
180+
Context context = IMApplication.getContext();
181+
path.add(context.getCacheDir().getAbsolutePath());
182+
path.add(context.getExternalCacheDir().getAbsolutePath());
183+
184+
return path;
185+
}
186+
187+
188+
private static long getEnvironmentSize() {
189+
File localFile = Environment.getDataDirectory();
190+
if (localFile == null)
191+
return 0L;
192+
193+
StatFs statFs = new StatFs(localFile.getPath());
194+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
195+
return statFs.getBlockCountLong() * statFs.getBlockSizeLong();
196+
}
197+
return statFs.getBlockCount() * statFs.getBlockSize();
198+
}
199+
200+
private static void freeStorageAndNotify(IPackageDataObserver.Stub observer) {
201+
202+
try {
203+
Context context = IMApplication.getContext();
204+
PackageManager pm = context.getPackageManager();
205+
LogUtil.i(TAG, "name:" + pm.getClass().getName());
206+
Method localMethod = pm.getClass().getMethod("freeStorageAndNotify", Long.TYPE,
207+
IPackageDataObserver.class);
208+
long localLong = Long.valueOf(getEnvironmentSize() - 1L);
209+
210+
localMethod.invoke(pm, localLong, observer);
211+
} catch (Exception e) {
212+
e.printStackTrace();
213+
}
214+
}
215+
216+
217+
}

android/src/main/java/com/netease/im/IMApplication.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,18 @@ private static LoginInfo getLoginInfo() {
139139
return LoginService.getInstance().getLoginInfo(context);
140140
}
141141

142+
public static String getSdkStorageRooPath(){
143+
return Environment.getExternalStorageDirectory() + "/" + context.getPackageName() + "/nim";
144+
}
142145
private static SDKOptions getOptions(Context context) {
143146
SDKOptions options = new SDKOptions();
144147

145148
// 如果将新消息通知提醒托管给SDK完成,需要添加以下配置。
146149
initStatusBarNotificationConfig(options, context);
147150

148151
// 配置保存图片,文件,log等数据的目录
149-
String sdkPath = Environment.getExternalStorageDirectory() + "/" + context.getPackageName() + "/nim";
150-
options.sdkStorageRootPath = sdkPath;
152+
153+
options.sdkStorageRootPath = getSdkStorageRooPath();
151154

152155
// 配置数据库加密秘钥
153156
options.databaseEncryptKey = "NETEASE";

android/src/main/java/com/netease/im/common/ImageLoaderKit.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,18 @@ public void clear() {
8181
cacheLoad.clear();
8282
}
8383

84+
public void clearCache(){
85+
// clear();
86+
ImageLoader.getInstance().clearDiskCache();
87+
}
88+
89+
public File getChacheDir(){
90+
return StorageUtils.getOwnCacheDirectory(context, context.getPackageName() + "/cache/image/");
91+
}
92+
8493
private ImageLoaderConfiguration getDefaultConfig() throws IOException {
8594
int MAX_CACHE_MEMORY_SIZE = (int) (Runtime.getRuntime().maxMemory() / 8);
86-
File cacheDir = StorageUtils.getOwnCacheDirectory(context, context.getPackageName() + "/cache/image/");
95+
File cacheDir = getChacheDir();
8796

8897
LogUtil.i(TAG, "ImageLoader memory cache size = " + MAX_CACHE_MEMORY_SIZE / M + "M");
8998
LogUtil.i(TAG, "ImageLoader disk cache directory = " + cacheDir.getAbsolutePath());
@@ -94,7 +103,7 @@ private ImageLoaderConfiguration getDefaultConfig() throws IOException {
94103
.threadPriority(Thread.NORM_PRIORITY - 2) // 降低线程的优先级,减小对UI主线程的影响
95104
.denyCacheImageMultipleSizesInMemory()
96105
.memoryCache(new LruMemoryCache(MAX_CACHE_MEMORY_SIZE))
97-
.discCache(new LruDiskCache(cacheDir, new Md5FileNameGenerator(), 0))
106+
.diskCache(new LruDiskCache(cacheDir, new Md5FileNameGenerator(), 0))
98107
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())
99108
.imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间
100109
.writeDebugLogs()
@@ -195,7 +204,7 @@ public static String getMemoryCachedAvatar(String url) {
195204

196205
File file = DiskCacheUtils.findInCache(key, ImageLoader.getInstance().getDiskCache());// 查询磁盘缓存示例
197206
if (file == null) {
198-
asyncLoadAvatarBitmapToCache(url);
207+
// asyncLoadAvatarBitmapToCache(url);
199208
}
200209
return file == null ? "" : file.getAbsolutePath();
201210
}

0 commit comments

Comments
 (0)