在JNI中采用调用Java代码来获取pacakge list,报错了,google之,说是一次传输数据过大,超过1M,后来将getInstalledPackages改为getInstalledApplications(同样能获取到package name),但是还是报错。
其实问题在于:这个传输超过1M是针对一系列IPC来说的,并不是单纯的一次IPC过程超过1M,我在之前的代码各种访问系统图片音乐资源,传输很多资源了,这一次,获取比较大的数据,直接总体超过1M了,所以报错。
不过据说这个作为一个bug在5.1中解决了(就是不能让其他IPC内容影响到这个获取包列表的内容,也就是单单来算这一个API获取的内容是不是超过一个数比如1M)
经过各种调查,这里做了一个弥补方案:
速度比较慢,只做备用。(注意:此为系统bug,在5.1已经修复)
static int getPackageListByCmd(char* packageList, const char* dirPath){
//列出三方包
const char* fileName = "/pm3";
int len = mystrlen(dirPath) + mystrlen(fileName) + 5;
char* filePath = (char*)calloc(len, sizeof(char));
char* cmd = (char*)calloc(len + 30, sizeof(char));
strcpy(cmd, "pm list packages -3 >");
strcat(cmd, filePath);
system(cmd);
free(cmd);
FILE* fp = fopen(filePath, "r");
if(!fp){
return 0;
}
char buffer[128];
char* p;
while(!feof(fp)){
if(fgets(buffer, 128, fp)){
if((p = strchr(buffer, ':')) != NULL){
strcat(packageList, p);
strcat(packageList, ",");
}
}
}
fclose(fp);
remove(filePath);
LOGI("getPackageListByCmd, result is %s", packageList);
return 1;
}
再给出他写的java方案:
public static List<PackageInfo> getInstalledPackages(Context context,int flags)
{
final PackageManager pm=context.getPackageManager();
try
{
return pm.getInstalledPackages(flags);
}
catch(Exception ignored)
{
//we don't care why it didn't succeed. We'll do it using an alternative way instead
}
// use fallback:
Process process;
List<PackageInfo> result=new ArrayList<>();
BufferedReader bufferedReader=null;
try
{
process=Runtime.getRuntime().exec("pm list packages");
bufferedReader=new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while((line=bufferedReader.readLine())!=null)
{
final String packageName=line.substring(line.indexOf(':')+1);
final PackageInfo packageInfo=pm.getPackageInfo(packageName,flags);
result.add(packageInfo);
}
process.waitFor();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(bufferedReader!=null)
try
{
bufferedReader.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
return result;
}
评论区