天天看點

android 關于多任務下載下傳問題 關于多任務下載下傳問題

近期項目中,遇到一個問題,清單資料中的圖檔位址是一個需要下載下傳JS再解析的字段,之前的圖檔下載下傳是一個異步的過程,由一個隊列處理。

Android系統以不同尋常的方式處理多個應用程式的同時運作。來自于其它不同平台的開發者或許會對這樣的運作機制感到很奇怪。而了解Android多任務的運作,對于設計出可以良好運作的應用程式,以及與Android平台的其它部分進行無縫結合都具有重要意義。這篇文章說明了Android的多任務方式設計上的成因,它對應用程式運作産生的影響,還有你可以怎樣更好地利用Android的這一特性。

public class ImageTaskExecutor { 

    /** 存放任務的連結清單,first-in last-out */ 

    private LinkedList<ImageTask> mTaskQueue = null; 

    /** 執行任務的線程 */ 

    private ThreadUnit mThreadUnit = null; 

    /** 執行任務的間隔時間 */ 

    public static final long WAIT_PERIOD = 50L; 

    private volatile boolean paused; 

    private final Object signal = new Object(); 

    /** 

     * 添加新任務 

     *  

     * @param task 

     * @return 是否添加成功 

     */ 

    public synchronized boolean addNewTask(final ImageTask task) { 

        if (mThreadUnit == null) { 

            mThreadUnit = new ThreadUnit(); 

            mTaskQueue = new LinkedList<ImageTask>(); 

            new Thread(mThreadUnit).start(); 

        } 

        return mTaskQueue.offer(task); 

    } 

    class ThreadUnit implements Runnable { 

        public boolean isRunning = false; 

        private ImageTask task = null; 

        @Override 

        public void run() { 

            try { 

                isRunning = true; 

                while (isRunning) { 

                    while (mTaskQueue != null && mTaskQueue.isEmpty()) { 

                        try { 

                            Thread.sleep(WAIT_PERIOD); 

                        } catch (InterruptedException e) { 

                            e.printStackTrace(); 

                        } 

                    } 

                    synchronized (signal) { 

                        while (paused) { // pause point 

                            signal.wait(); 

                    if (mTaskQueue != null && !mTaskQueue.isEmpty()) { 

                        task = mTaskQueue.removeFirst(); // 取對外連結表中的最後一個任務 

                        if (task != null) { 

                            task.execute(); 

                } // end while 

            } catch (Exception e) { 

                e.toString(); 

            } 

        } // end run 

     * 中斷任務的執行 

    public void pauseTaskThread() { 

        setPaused(); 

    private void setPaused() { 

        synchronized (signal) { 

            paused = true; 

    private void setUnpaused() { 

            paused = false; 

            signal.notify(); 

     * 恢複任務的執行 

    public void resumeTaskThread(){ 

        setUnpaused(); 

     * 終止任務的執行 

    public void terminateTaskThread() { 

        if (mThreadUnit != null) { 

            mThreadUnit.isRunning = false; 

        if (mTaskQueue != null) { 

            mTaskQueue.clear(); 

        mThreadUnit = null; 

        mTaskQueue = null; 

現在清單中的圖檔資訊需要解析,如果再開一個隊列,頁面直接卡得不動了。。。

然後,這時候就考濾整個下載下傳JS然後再下載下傳圖檔這個過程需要使用同步操作了

後來發現,這個過程操作會比較長,頁面的開始出現第一項的圖檔閃跳

原來adapter裡面的getView 方法,被調用的過程中,contentview裡面的内容會被随機複用,然後就。。。

public void inflateTaobaoImage(final String jsonUrl, final View view, 

            final int error_bg_Id) { 

        if (jsonUrl == null || jsonUrl.equals("")) { 

            return; 

        String imgUrl = getImgUrl(jsonUrl); 

        if (!TextUtils.isEmpty(imgUrl)) { 

            final String originJsonUrl = (String) view.getTag(IMG_TAG); 

            if (TextUtils.equals(originJsonUrl, jsonUrl)) { 

                LogsPrinter.debugError(TAG, "inflateTaobaoImage in HashMap " 

                        + originJsonUrl + " " + view); 

                inflateImage(imgUrl, view, error_bg_Id); 

        } else { 

            mTaskExecutor.addNewTask(new ImageTask(jsonUrl) { 

                @Override 

                public void execute() { 

                    String taobaoImgUrl = downloadUrlString(jsonUrl 

                            + "&callback=success_jsonpCallback"); 

                    final String imgUrl = getTaobaoImageUrl(taobaoImgUrl); 

                    LogsPrinter.debugError("add map", imgUrl + " " + jsonUrl); 

                    taobaoImgMap.add(imgUrl, jsonUrl); 

                    final String originJsonUrl = (String) view.getTag(IMG_TAG); 

                    if (TextUtils.equals(originJsonUrl, jsonUrl)) { 

                        baseHandlers.post(new Runnable() { 

                            @Override 

                            public void run() { 

                                inflateImage(imgUrl, view, error_bg_Id); 

                            } 

                        }); 

                } 

            }); 

值得注意的一個問題是:

settag的值需要是一個固定的值。不然,有時候會出現加載多次的情況。。

繼續閱讀