AsyncTask的使用

    後臺獲取手機安裝的apk列表,其中分爲系統apk與非系統apk以及獲取root權限之後的隱藏apk,默認通過apk名稱排序。使用RecycleView,RecycleView.Adapter<Adapter.appViewHolder>,appViewHolder繼承自RecycleView.Adapter,其中依賴部分開源代碼progressWheel,fastScoller,pullToRefreshView等。

   先將具體邏輯代碼貼上, 後面再介紹AsyncTask的使用。

class getInstalledApps extends AsyncTask<Void, String, Void> {
        private Integer totalApps;
        private Integer actualApps;

        public getInstalledApps() {
            actualApps = 0;

            appList = new ArrayList<>();
            appSystemList = new ArrayList<>();
            appHiddenList = new ArrayList<>();
        }

        @Override
        protected Void doInBackground(Void... params) {
            final PackageManager packageManager = getPackageManager();
            List<PackageInfo> packages = packageManager.getInstalledPackages(PackageManager.GET_META_DATA);
            Set<String> hiddenApps = appPreferences.getHiddenApps();
            totalApps = packages.size() + hiddenApps.size();
            // Get Sort Mode 獲取apk列表後的排序方式
            switch (appPreferences.getSortMode()) {
                default:
                    // Comparator by Name (default)
                    Collections.sort(packages, new Comparator<PackageInfo>() {
                        @Override
                        public int compare(PackageInfo p1, PackageInfo p2) {
                            return packageManager.getApplicationLabel(p1.applicationInfo).toString().toLowerCase().compareTo(packageManager.getApplicationLabel(p2.applicationInfo).toString().toLowerCase());
                        }
                    });
                    break;
                case "2":
                    // Comparator by Size
                    Collections.sort(packages, new Comparator<PackageInfo>() {
                        @Override
                        public int compare(PackageInfo p1, PackageInfo p2) {
                            Long size1 = new File(p1.applicationInfo.sourceDir).length();
                            Long size2 = new File(p2.applicationInfo.sourceDir).length();
                            return size2.compareTo(size1);
                        }
                    });
                    break;
                case "3":
                    // Comparator by Installation Date 
                    Collections.sort(packages, new Comparator<PackageInfo>() {
                        @Override
                        public int compare(PackageInfo p1, PackageInfo p2) {
                            return Long.toString(p2.firstInstallTime).compareTo(Long.toString(p1.firstInstallTime));
                        }
                    });
                    break;
                case "4":
                    // Comparator by Last Update
                    Collections.sort(packages, new Comparator<PackageInfo>() {
                        @Override
                        public int compare(PackageInfo p1, PackageInfo p2) {
                            return Long.toString(p2.lastUpdateTime).compareTo(Long.toString(p1.lastUpdateTime));
                        }
                    });
                    break;
            }

            // Installed & System Apps
            for (PackageInfo packageInfo : packages) {
                if (!(packageManager.getApplicationLabel(packageInfo.applicationInfo).equals("") || packageInfo.packageName.equals(""))) {
                    
                    if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                        try {
                            // Non System Apps
                            AppInfo tempApp = new AppInfo(packageManager.getApplicationLabel(packageInfo.applicationInfo).toString(), packageInfo.packageName, packageInfo.versionName, packageInfo.applicationInfo.sourceDir, packageInfo.applicationInfo.dataDir, packageManager.getApplicationIcon(packageInfo.applicationInfo), false);
                            appList.add(tempApp);
                        } catch (OutOfMemoryError e) {
                            //TODO Workaround to avoid FC on some devices (OutOfMemoryError). Drawable should be cached before.
                            AppInfo tempApp = new AppInfo(packageManager.getApplicationLabel(packageInfo.applicationInfo).toString(), packageInfo.packageName, packageInfo.versionName, packageInfo.applicationInfo.sourceDir, packageInfo.applicationInfo.dataDir, getResources().getDrawable(R.drawable.ic_android), false);
                            appList.add(tempApp);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else {
                        try {
                            // System Apps
                            AppInfo tempApp = new AppInfo(packageManager.getApplicationLabel(packageInfo.applicationInfo).toString(), packageInfo.packageName, packageInfo.versionName, packageInfo.applicationInfo.sourceDir, packageInfo.applicationInfo.dataDir, packageManager.getApplicationIcon(packageInfo.applicationInfo), true);
                            appSystemList.add(tempApp);
                        } catch (OutOfMemoryError e) {
                            //TODO Workaround to avoid FC on some devices (OutOfMemoryError). Drawable should be cached before.
                            AppInfo tempApp = new AppInfo(packageManager.getApplicationLabel(packageInfo.applicationInfo).toString(), packageInfo.packageName, packageInfo.versionName, packageInfo.applicationInfo.sourceDir, packageInfo.applicationInfo.dataDir, getResources().getDrawable(R.drawable.ic_android), false);
                            appSystemList.add(tempApp);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }

                actualApps++;
                publishProgress(Double.toString((actualApps * 100) / totalApps));//調用publishProgress()方法,通知onProgressUpdate()更新主線程UI
            }

            // Hidden Apps
            for (String app : hiddenApps) {
                AppInfo tempApp = new AppInfo(app);
                Drawable tempAppIcon = UtilsApp.getIconFromCache(context, tempApp);
                tempApp.setIcon(tempAppIcon);
                appHiddenList.add(tempApp);

                actualApps++;
                publishProgress(Double.toString((actualApps * 100) / totalApps));
            }

            return null;
        }

        @Override
        protected void onProgressUpdate(String... progress) {
            super.onProgressUpdate(progress);
            progressWheel.setProgress(Float.parseFloat(progress[0]));//gradle中添加依賴compile 'com.pnikosis:materialish-progress:1.7'
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            appAdapter = new AppAdapter(appList, context);
            appSystemAdapter = new AppAdapter(appSystemList, context);
            appFavoriteAdapter = new AppAdapter(getFavoriteList(appList, appSystemList), context);
            appHiddenAdapter = new AppAdapter(appHiddenList, context);

            fastScroller.setVisibility(View.VISIBLE);//compile 'xyz.danoz:recycleviewfastscroller:0.1.3'
            recyclerView.setAdapter(appAdapter);
            pullToRefreshView.setEnabled(true);//compile 'com.yalantis:phoenix:1.2.2'
            progressWheel.setVisibility(View.GONE);
            searchItem.setVisible(true);

            fastScroller.setRecyclerView(recyclerView);
            recyclerView.setOnScrollListener(fastScroller.getOnScrollListener());

            setPullToRefreshView(pullToRefreshView);
            drawer.closeDrawer();
            drawer = UtilsUI.setNavigationDrawer((Activity) context, context, toolbar, appAdapter, appSystemAdapter, appFavoriteAdapter, appHiddenAdapter, recyclerView);
        }

    }

AsyncTask相對簡單的結構。

public class MyTask extends AsyncTask<Object, Integer, Integer> {
//執行前準備
@Override
protected void onPreExecute() {
    super.onPreExecute();
}

//執行
@Override
protected void doInBackground(Object... params) {
    publishProgress(Integer);//將調用onProgressUpdate()方法通知主線程刷新UI,因爲在子線程中刷新UI會報錯
}

//進度更新
@Override
protected void onProgressUpdate(Integer... progress) {
    //do somthing
}

//執行完
@Override
protected void onPostExecute(Integer result) {
    //do somthing
}

//取消執行
@Override
protected void onCancelled() {
    super.onCancelled();
}


上例MyTask繼承AysncTask使用了3個範型:Object,Integer,Integer。

    第1個範型指定了 doInBackground()方法的參數類型是一個不定長的Object數組。當主線程中用execute()方法啓動MyTask線程時,我們會傳遞一些參數給doInBackground()方法。

    第2個範型指定了onProgressUpdate()方法的參數類型爲Integer不定長數組。因爲這個方法只會在調用publishProgress()方法時調用,而我們只在doInBackground()方法中調用過publishProgress()方法。我們只需傳遞一個表示進度的整數給它就可以了。

    第3個範型指定了onPostExecute()方法的參數類型。

    doInBackground()方法在線程被execute()啓動時調用(只有一次)。在該方法中,建立線程循環以完成某些工作。在每次循環完成時,我們通過手動調用publishProgress()(可調用多次)方法,通知onProgressUpdate方法更新主線程的UI(調用多次)。當所有循環完成後,線程循環結束,自動調用onPostExecute()方法返回結果(調用一次),線程銷燬。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章