使用 AsyncTaskLoader 加载 JSON 时冻结 UI

Freezing UI while loading JSON using AsyncTaskLoader

我想从本地数据库加载一些数据,为此我正在使用 AsynctaskLoader。但是在加载数据时我无法与屏幕交互。整个 UI 冻结。我做了一些研究,发现应该在工作线程上初始化 AsyncTaskLoader 以将整个进程移动到工作线程上,我也尝试过这样做,但我再次冻结在 UI.

这是我的 AsyncTaskLoader class

public class ArticleDatabaseLoader extends AsyncTaskLoader<List<Article>> {

private int code = 0;

public ArticleDatabaseLoader(Context context, int code) {
    super(context);
    this.code = code;
}

@Override
public List<Article> loadInBackground() {
    List<Article> articleList = new ArrayList<>();
    ArticleTable articleTable = new ArticleTable(getContext());
    ArticleCategory categoryTable = new ArticleCategory(getContext());
    switch (code) {
        case ArticleList:
            articleTable.open();
            categoryTable.open();
            List<String> selected_category = new ArrayList<>();
            for (int i = 0; i < 5; i++) {   /* saving all the selected categories */
                if (getCategoryStatus(getContext(), categories[i]) == 1) {
                    selected_category.add(categories[i]);
                }
            }
            StringBuilder where_query =  new StringBuilder();
            if (selected_category.size() > 0){  /* building the where query for sql */
                for (int i = 0; i < selected_category.size(); i++) {
                    if (i == selected_category.size() - 1) {
                        where_query.append(String.format("%s = '%s'",
                                DBColumn.ArticleCategoryColumn.category_id,
                                selected_category.get(i)));
                    } else {
                        where_query.append(String.format("%s = '%s' OR ",
                                DBColumn.ArticleCategoryColumn.category_id,
                                selected_category.get(i)));
                    }
                }
                Cursor selectedCursor = categoryTable.getArticles(where_query.toString());
                if (selectedCursor != null && selectedCursor.moveToFirst() && selectedCursor.getCount() > 0) {
                    do {
                        String articleId = selectedCursor.getString(selectedCursor.getColumnIndex(DBColumn.ArticleCategoryColumn.article_id));
                        Cursor articleCursor = articleTable.getArticleById(articleId);
                        if (articleCursor != null && articleCursor.moveToFirst()) {
                            articleList.add(articleTable.articleObject(getContext(),articleCursor));
                        }
                        articleCursor.close();
                    } while (selectedCursor.moveToNext());
                }
                if (selectedCursor != null)
                    selectedCursor.close();
            } else {
                Cursor articleListCursor = articleTable.getAllArticles();
                if (articleListCursor != null && articleListCursor.moveToFirst() && articleListCursor.getCount() > 0) {
                    do {
                        articleList.add(articleTable.articleObject(getContext(),articleListCursor));
                    } while (articleListCursor.moveToNext());
                }
                if (articleListCursor != null)
                    articleListCursor.close();
            }
            articleTable.close();
            categoryTable.close();
            return articleList;
    }

    return null;
}
}

这是我的 onCreateMethod

@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    ArticleTable articleTable = new ArticleTable(this);
    articleTable.open();
    if (articleTable.getAllArticles() != null) {
        /* load the data from local database */
        getSupportLoaderManager().initLoader(Loader_ID, null, ArticleListActivity.this).forceLoad();
    } else {
        ApiManager.getArticles(this, this);
    }
    articleTable.close();
}

Create Async task to load data from database, when complete set adapter

MainActivity execute asynctask in oncreate and set adapter in call back method
public class MainActivity extends AppCompatActivity implements
 ArticleDatabaseLoader.ArticleDatabaseLoaderHandler{
{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        new ArticleDatabaseLoader(MainActivity.this,0).execute();
    }

    @Override
    public void ArticleDatabaseLoaderComplete(List<Article> articleList) {
        if(articleList.size() > 0)
        {
            // refresh your adapter
        }
    }
}

Create ArticleDatabaseLoader class

import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;

import java.util.ArrayList;
import java.util.List;


public class ArticleDatabaseLoader extends AsyncTask<String, String, String> {
    private int code = 0;
    List<Article> articleList = new ArrayList<>();
    protected Context mCtx;
    ArticleDatabaseLoaderHandler handler;
    public interface ArticleDatabaseLoaderHandler {
        void ArticleDatabaseLoaderComplete(List<Article> articleList);
    }

    public ArticleDatabaseLoader(Context context, int code) {
        mCtx = context;
        this.code = code;
        this.handler = (ArticleDatabaseLoaderHandler) context;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // todo display progress bar
    }
    @Override
    protected String doInBackground(String... strings) {
        ArticleTable articleTable = new ArticleTable(mCtx);
        ArticleCategory categoryTable = new ArticleCategory(mCtx);
        switch (code) {
            case ArticleList:
                articleTable.open();
                categoryTable.open();
                List<String> selected_category = new ArrayList<>();
                for (int i = 0; i < 5; i++) {   /* saving all the selected categories */
                    if (getCategoryStatus(mCtx, categories[i]) == 1) {
                        selected_category.add(categories[i]);
                    }
                }
                StringBuilder where_query = new StringBuilder();
                if (selected_category.size() > 0) {  /* building the where query for sql */
                    for (int i = 0; i < selected_category.size(); i++) {
                        if (i == selected_category.size() - 1) {
                            where_query.append(String.format("%s = '%s'",
                                    DBColumn.ArticleCategoryColumn.category_id,
                                    selected_category.get(i)));
                        } else {
                            where_query.append(String.format("%s = '%s' OR ",
                                    DBColumn.ArticleCategoryColumn.category_id,
                                    selected_category.get(i)));
                        }
                    }
                    Cursor selectedCursor = categoryTable.getArticles(where_query.toString());
                    if (selectedCursor != null && selectedCursor.moveToFirst() && selectedCursor.getCount() > 0) {
                        do {
                            String articleId = selectedCursor.getString(selectedCursor.getColumnIndex(DBColumn.ArticleCategoryColumn.article_id));
                            Cursor articleCursor = articleTable.getArticleById(articleId);
                            if (articleCursor != null && articleCursor.moveToFirst()) {
                                articleList.add(articleTable.articleObject(mCtx, articleCursor));
                            }
                            articleCursor.close();
                        } while (selectedCursor.moveToNext());
                    }
                    if (selectedCursor != null)
                        selectedCursor.close();
                } else {
                    Cursor articleListCursor = articleTable.getAllArticles();
                    if (articleListCursor != null && articleListCursor.moveToFirst() && articleListCursor.getCount() > 0) {
                        do {
                            articleList.add(articleTable.articleObject(getContext(), articleListCursor));
                        } while (articleListCursor.moveToNext());
                    }
                    if (articleListCursor != null)
                        articleListCursor.close();
                }
                articleTable.close();
                categoryTable.close();

                return null;

        }
    }
    protected void onPostExecute(String results) {
        // todo dismiss progress bar
        handler.ArticleDatabaseLoaderComplete(articleList);
    }
}