public static String[] getVolumePaths(Context ctx) {
if(enable){
StorageManager manager = (StorageManager) ctx.getSystemService(Context.STORAGE_SERVICE);
try {
return (String[]) getVolumePaths.invoke(manager);
} catch (Exception e) {
Timber.d(e, "getVolumePaths failed");
}
}
return new String[]{ Environment.getExternalStorageDirectory().getPath() };
}
public static String[] getVolumePaths(StorageManager manager) {
if(enable){
try {
return (String[]) getVolumePaths.invoke(manager);
} catch (Exception e) {
Timber.d(e, "getVolumePaths failed");
}
}
return new String[]{ Environment.getExternalStorageDirectory().getPath() };
}
上面 这两种实现大家觉得哪个好些,第一种传的是 Context,使用起来比较方便,但是会导致调用getSystemService比较频繁,调用getSystemService会不会导致性能问题,第二种传的是SERVICE,不会调用getSystemService,但是使用起来比较麻烦
我喜欢这样写
public static String[] getVolumePaths() {
if (enable) {
StorageManager manager = (StorageManager) MyApplication.mContext
.getSystemService(Context.STORAGE_SERVICE);
try {
return (String[]) getVolumePaths.invoke(manager);
} catch (Exception e) {
Timber.d(e, "getVolumePaths failed");
}
}
return new String[] { Environment.getExternalStorageDirectory()
.getPath() };
}
自定义Application,在Application内放一个指向自己的静态mContext,在Application的onCreate中给它赋值。
因为Application的生命周期和App的生命周期一样...所以使用静态变量也不会遇到内存泄露问题,由于生命周期完全一致,也不会遇到取不到的问题。
凡是使用Application Context就可以的地方我都这样处理,有些地方你拿不到Context对象,或者我不希望这个模块和Activity Context产生关联(避免泄露),要传也挺麻烦的。
下面贴一点getSystemService的源代码
里面基本没有逻辑,我觉得不会产生性能问题,都是直接返回你要取的对象
直接返回:
@Override
public Object getSystemService(@ServiceName @NonNull String name) {
if (getBaseContext() == null) {
throw new IllegalStateException(
"System services not available to Activities before onCreate()");
}
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
return super.getSystemService(name);
}
只构造一次:
@Override public Object getSystemService(String name) {
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
}
return mInflater;
}
return getBaseContext().getSystemService(name);
}
其它的在BaseContext里,没找到源码,谁找到了告诉我下在哪。 ContextWrapper.mBase这个到底传进来的类型是什么找不到.
用第一种,调用getSystemService 的时候,内部的实现会做缓存,不用担心性能问题