Android,method.invoke在SDK 26(奥利奥)中崩溃? [英] Android, method.invoke crashes in SDK 26, Oreo?

查看:82
本文介绍了Android,method.invoke在SDK 26(奥利奥)中崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我在StackOverflow上的第一篇文章.

This is my first post on StackOverflow.

我已经在我的增强应用程序中使用了反射,如下所示.它在sdk< 26中效果很好,但是在sdk 26中,我得到了java.lang.reflect.InvocationTargetException异常.如何在Android 8中恢复正常工作?

I have used the reflection in my boosting app like below. It works well in sdk<26 but in sdk 26 I get the java.lang.reflect.InvocationTargetException exception. How can I bring it back to work in android 8?

我的代码如下:

Method pkgMethod = getPackageManager().getClass().getMethod("getPackageSizeInfo", String.class, IPackageStatsObserver.class);
pkgMethod.invoke(getPackageManager(), pkg.packageName, new IPackageStatsObserver.Stub() {
                @Override
                public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {
                    long cacheSize = pStats.externalCacheSize;
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
                        cacheSize += pStats.cacheSize;
                    if (cacheSize > 0) {
                        Drawable icon = null;
                        try {
                            icon = getPackageManager().getApplicationIcon(pkg.packageName);
                        } catch (PackageManager.NameNotFoundException ignored) {
                        }
                        String name = pkg.packageName;
                        try {
                            PackageManager pm = getApplicationContext().getPackageManager();
                            name = (String) pm.getApplicationLabel(pm.getApplicationInfo(pkg.packageName, PackageManager.GET_META_DATA));
                        } catch (PackageManager.NameNotFoundException e) {
                            e.printStackTrace();
                        }
                        totalSize += cacheSize;
                        appList.add(new Items(icon, name, pkg.packageName, cacheSize, true, ""));

                        publishProgress();
                    }
                    countDownLatch.countDown();
                }
            });

这是我得到的例外情况:

And here is the exception I get:

java.lang.reflect.InvocationTargetException
04-05 05:20:14.027 2701-4724/com.mydidantivirus.android W/System.err:     
at java.lang.reflect.Method.invoke(Native Method)
04-05 05:20:14.027 2701-4724/com.myantivirus.android W/System.err:     
at com.my.antivirus.ui.JunkFileActivity$ScanTask.doInBackground(JunkFileActivity.java:285)
04-05 05:20:14.028 2701-4724/com.myantivirus.android W/System.err:     at com.my.antivirus.ui.JunkFileActivity$ScanTask.doInBackground(JunkFileActivity.java:260)
04-05 05:20:14.028 2701-4724/com.myantivirus.android W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:333)
04-05 05:20:14.029 2701-4724/com.myantivirus.android W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
04-05 05:20:14.029 2701-4724/com.myantivirus.android W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
04-05 05:20:14.029 2701-4724/com.myantivirus.android W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
04-05 05:20:14.029 2701-4724/com.myantivirus.android W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
04-05 05:20:14.029 2701-4724/com.myantivirus.android W/System.err:     at java.lang.Thread.run(Thread.java:764)
04-05 05:20:14.030 2701-4724/com.myantivirus.android W/System.err: Caused by: java.lang.NullPointerException: Attempt to read from field 'long android.content.pm.PackageStats.externalCacheSize' on a null object reference
04-05 05:20:14.030 2701-4724/com.myantivirus.android W/System.err:     at com.my.antivirus.ui.JunkFileActivity$ScanTask$1.onGetStatsCompleted(JunkFileActivity.java:288)
04-05 05:20:14.030 2701-4724/com.myantivirus.android W/System.err:     at android.app.ApplicationPackageManager.getPackageSizeInfoAsUser(ApplicationPackageManager.java:2167)
04-05 05:20:14.030 2701-4724/com.myantivirus.android W/System.err:     at android.content.pm.PackageManager.getPackageSizeInfo(PackageManager.java:5065)
04-05 05:20:14.030 2701-4724/com.myantivirus.android W/System.err:  ... 9 more

我还尝试了Android Oreo上的缓存清理器库,但遇到了以下异常:

I also tried a cache cleaner library on Android Oreo and got this exception:

java.lang.reflect.InvocationTargetException
04-05 06:50:46.590 8639-8741/org.mazhuang.cleanexpert W/System.err:     at 
java.lang.reflect.Method.invoke(Native Method)
04-05 06:50:46.590 8639-8741/org.mazhuang.cleanexpert W/System.err:     at org.mazhuang.cleanexpert.util.CleanUtil.freeAllAppsCache(CleanUtil.java:96)
04-05 06:50:46.591 8639-8741/org.mazhuang.cleanexpert W/System.err:     at org.mazhuang.cleanexpert.ui.JunkCleanActivity$5.run(JunkCleanActivity.java:306)
04-05 06:50:46.591 8639-8741/org.mazhuang.cleanexpert W/System.err:     at java.lang.Thread.run(Thread.java:764)
04-05 06:50:46.591 8639-8741/org.mazhuang.cleanexpert W/System.err: Caused by: java.lang.SecurityException: Neither user 10087 nor current process has android.permission.CLEAR_APP_CACHE.
04-05 06:50:46.591 8639-8741/org.mazhuang.cleanexpert W/System.err:     at android.os.Parcel.readException(Parcel.java:1942)
04-05 06:50:46.591 8639-8741/org.mazhuang.cleanexpert W/System.err:     at android.os.Parcel.readException(Parcel.java:1888)
04-05 06:50:46.591 8639-8741/org.mazhuang.cleanexpert W/System.err:     at android.content.pm.IPackageManager$Stub$Proxy.freeStorageAndNotify(IPackageManager.java:4865)
04-05 06:50:46.591 8639-8741/org.mazhuang.cleanexpert W/System.err:     at android.app.ApplicationPackageManager.freeStorageAndNotify(ApplicationPackageManager.java:2112)
04-05 06:50:46.592 8639-8741/org.mazhuang.cleanexpert W/System.err:     at android.content.pm.PackageManager.freeStorageAndNotify(PackageManager.java:4996)
04-05 06:50:46.593 8639-8741/org.mazhuang.cleanexpert W/System.err:     ... 4 more

推荐答案

已更新

从Android O(API级别26)开始,您不能将getPackageSizeInfo方法用于反思.以下是可以在api级别26以下及其上提供帮助的代码:

From Android O (API level 26) you can not use getPackageSizeInfo method with reflaction. Following is a code that can help you for both below api level 26 and above it:

private void getPackageSizeInfo(final Context context, String packageName) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        final StorageStatsManager storageStatsManager = (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE);
        final StorageManager storageManager = (StorageManager)  context.getSystemService(Context.STORAGE_SERVICE);
        try {

            ApplicationInfo ai = context.getPackageManager().getApplicationInfo(packageName, 0);
            StorageStats storageStats = storageStatsManager.queryStatsForUid(ai.storageUuid, getApplicationInfo().uid);
            long cacheSize =storageStats.getCacheBytes();
            long dataSize =storageStats.getDataBytes();
            long apkSize =storageStats.getAppBytes();
            Toast.makeText(context, cacheSize + ",," + dataSize + ",," + apkSize, Toast.LENGTH_LONG).show();
            //long size += info.cacheSize;
        } catch (Exception e) {
            e.printStackTrace();
        }
    } else  {
        Method getPackageSizeInfo;
        try {
            getPackageSizeInfo = context.getPackageManager().getClass()
                .getMethod("getPackageSizeInfo",
                    String.class, Class.forName("android.content.pm.IPackageStatsObserver"));

            getPackageSizeInfo.invoke(context.getPackageManager(), packageName,
                new IPackageStatsObserver.Stub() { //error

                    public void onGetStatsCompleted(
                        PackageStats pStats, boolean succeeded)
                        throws RemoteException {

                        //totalSize = totalSize + pStats.cacheSize;
                        //Log.d("size", totalSize+"");
                        Toast.makeText(getApplicationContext(), "size"+pStats.cacheSize + ",," + pStats.dataSize + ",," + pStats.codeSize, Toast.LENGTH_SHORT).show();
                    }
                }
            );
        } catch (Exception e) {
            try {
                getPackageSizeInfo = context.getPackageManager().getClass()
                    .getMethod("getPackageSizeInfo",
                        String.class, Class.forName("android.content.pm.IPackageStatsObserver"));

                getPackageSizeInfo.invoke(context.getPackageManager(), packageName,
                    new IPackageStatsObserver.Stub() { //error

                        public void onGetStatsCompleted(
                            PackageStats pStats, boolean succeeded)
                            throws RemoteException {
                            Toast.makeText(getApplicationContext(), "size"+pStats.cacheSize, Toast.LENGTH_SHORT).show();
                        }
                    }
                );
            } catch (Exception ee) {
                Log.d("eeeeeeeeeee", "error");
                ee.printStackTrace();
            }
        }
    }
}

请注意,对于低于26的API级别以使代码正常工作,您应根据以下内容配置AIDL和要求: https://stackoverflow.com/a/30278018/1939409

Please notice that for API level below 26 for making the code work, you should configure AIDL and the requirments according to: https://stackoverflow.com/a/30278018/1939409

这篇关于Android,method.invoke在SDK 26(奥利奥)中崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆