2013-04-24 53 views
0

我有一個自定義CursorAdapter,它在其bindView方法中使用多個AsyncTask來將圖像加載到網格中。防止AsyncTask在綁定中多次運行查看

bindView運行我的AsyncTask s獲得多次啓動。這具有推高我的堆大小並可能導致內存不足錯誤的效果。

什麼是最好的方法,讓AsyncTask s只運行一次?

+0

使用一個'Loader',如所描述的[**這裏**](HTTP://www.androiddesignpatterns。 COM/2012/07 /裝載機和-loadermanager-background.html)。 – 2013-04-24 18:02:53

+0

@AlexLockwood因此,如果我們按照你的建議使用'loader',這個'loader'只會被啓動一次?不像和'AsyncTask'? – HGPB 2013-04-24 22:25:38

+0

你的'AsyncTask'獲取什麼數據...?一個'光標'?或者是其他東西? – 2013-04-24 22:53:42

回答

0

您可以緩存Asynctask的結果。 Github上有一個非常有用的項目,您可能需要查看。 https://github.com/nostra13/Android-Universal-Image-Loader

+0

麻煩的是,在幾毫秒內''bindView''可以被多次調用。 'AsyncTask'的結果在下一個'AsyncTask'被啓動的時候還沒有被返回。 – HGPB 2013-04-24 19:51:06

0

我認爲您正在尋找AsyncTaskLoader或其support package的實施。它爲你處理所有事情。

的如何使用它的示例:

public SampleLoader extends AsyncTaskLoader<List<SampleItem>> { 

    // We hold a reference to the Loader’s data here. 
    private List<SampleItem> mData; 

    public SampleLoader(Context ctx) { 
    // Loaders may be used across multiple Activitys (assuming they aren't 
    // bound to the LoaderManager), so NEVER hold a reference to the context 
    // directly. Doing so will cause you to leak an entire Activity's context. 
    // The superclass constructor will store a reference to the Application 
    // Context instead, and can be retrieved with a call to getContext(). 
    super(ctx); 
    } 

    /****************************************************/ 
    /** (1) A task that performs the asynchronous load **/ 
    /****************************************************/ 

    @Override 
    public List<SampleItem> loadInBackground() { 
    // This method is called on a background thread and should generate a 
    // new set of data to be delivered back to the client. 
    List<SampleItem> data = new ArrayList<SampleItem>(); 

    // TODO: Perform the query here and add the results to 'data'. 

    return data; 
    } 

    /********************************************************/ 
    /** (2) Deliver the results to the registered listener **/ 
    /********************************************************/ 

    @Override 
    public void deliverResult(List<SampleItem> data) { 
    if (isReset()) { 
     // The Loader has been reset; ignore the result and invalidate the data. 
     releaseResources(data); 
     return; 
    } 

    // Hold a reference to the old data so it doesn't get garbag ecollected. 
    // We must protect it until the new data has been delivered. 
    List<SampleItem> oldData = mData; 
    mData = data; 

    if (isStarted()) { 
     // If the Loader is in a started state, deliver the results to the 
     // client. The superclass method does this for us. 
     super.deliverResult(data); 
    } 

    // Invalidate the old data as we don't need it any more. 
    if (oldData != null && oldData != data) { 
     releaseResources(oldData); 
    } 
    } 

    /*********************************************************/ 
    /** (3) Implement the Loader’s state-dependent behavior **/ 
    /*********************************************************/ 

    @Override 
    protected void onStartLoading() { 
    if (mData != null) { 
     // Deliver any previously loaded data immediately. 
     deliverResult(mData); 
    } 

    // Begin monitoring the underlying data source. 
    if (mObserver == null) { 
     mObserver = new SampleObserver(); 
     // TODO: register the observer 
    } 

    if (takeContentChanged() || mData == null) { 
     // When the observer detects a change, it should call onContentChanged() 
     // on the Loader, which will cause the next call to takeContentChanged() 
     // to return true. If this is ever the case (or if the current data is 
     // null), we force a new load. 
     forceLoad(); 
    } 
    } 

    @Override 
    protected void onStopLoading() { 
    // The Loader is in a stopped state, so we should attempt to cancel the 
    // current load (if there is one). 
    cancelLoad(); 

    // Note that we leave the observer as is. Loaders in a stopped state 
    // should still monitor the data source for changes so that the Loader 
    // will know to force a new load if it is ever started again. 
    } 

    @Override 
    protected void onReset() { 
    // Ensure the loader has been stopped. 
    onStopLoading(); 

    // At this point we can release the resources associated with 'mData'. 
    if (mData != null) { 
     releaseResources(mData); 
     mData = null; 
    } 

    // The Loader is being reset, so we should stop monitoring for changes. 
    if (mObserver != null) { 
     // TODO: unregister the observer 
     mObserver = null; 
    } 
    } 

    @Override 
    public void onCanceled(List<SampleItem> data) { 
    // Attempt to cancel the current asynchronous load. 
    super.onCanceled(data); 

    // The load has been canceled, so we should release the resources 
    // associated with 'data'. 
    releaseResources(data); 
    } 

    private void releaseResources(List<SampleItem> data) { 
    // For a simple List, there is nothing to do. For something like a Cursor, we 
    // would close it in this method. All resources associated with the Loader 
    // should be released here. 
    } 

    /*********************************************************************/ 
    /** (4) Observer which receives notifications when the data changes **/ 
    /*********************************************************************/ 

    // NOTE: Implementing an observer is outside the scope of this post (this example 
    // uses a made-up "SampleObserver" to illustrate when/where the observer should 
    // be initialized). 

    // The observer could be anything so long as it is able to detect content changes 
    // and report them to the loader with a call to onContentChanged(). For example, 
    // if you were writing a Loader which loads a list of all installed applications 
    // on the device, the observer could be a BroadcastReceiver that listens for the 
    // ACTION_PACKAGE_ADDED intent, and calls onContentChanged() on the particular 
    // Loader whenever the receiver detects that a new application has been installed. 
    // Please don’t hesitate to leave a comment if you still find this confusing! :) 
    private SampleObserver mObserver; 
} 

源:androiddesignpatterns.com - Implementing Loaders (part 3)

+0

請注意,如果OP的應用程序使用「ContentProvider」,那麼他最好使用「CursorLoader」而不是創建自己的「AsyncTaskLoader」子類。 – 2013-04-24 22:50:51