Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在RecyclerView中异步加载数据?_Java_Android_Android Recyclerview - Fatal编程技术网

Java 如何在RecyclerView中异步加载数据?

Java 如何在RecyclerView中异步加载数据?,java,android,android-recyclerview,Java,Android,Android Recyclerview,我在一个片段中有一个空白的回收器视图。收到GCM通知后,我想调用Web服务。该Web服务将数据存储到一个空白数据库中。当所有这些都完成后,我如何通知recycler视图使用新的数据库内容更新自身 我只停留在我需要通知回收者视图以更新自身的部分。我实现了这一点,但它只有在数据库中已有数据时才起作用。它在我的场景中不起作用 我正在提供我目前拥有的代码,以便更好地理解该问题: package mypackage; import android.app.Activity; import android

我在一个片段中有一个空白的回收器视图。收到GCM通知后,我想调用Web服务。该Web服务将数据存储到一个空白数据库中。当所有这些都完成后,我如何通知recycler视图使用新的数据库内容更新自身

我只停留在我需要通知回收者视图以更新自身的部分。我实现了这一点,但它只有在数据库中已有数据时才起作用。它在我的场景中不起作用

我正在提供我目前拥有的代码,以便更好地理解该问题:

package mypackage;

import android.app.Activity;
import android.app.LoaderManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.OvershootInterpolator;

import com.squareup.picasso.Picasso;

import mypackage.R;
import mypackage.adapters.NewsRecyclerViewAdapter;
import mypackage.database.NewsProvider;
import mypackage.models.News;
import mypackage.utils.SaveImageTask;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Random;

import butterknife.ButterKnife;
import jp.wasabeef.recyclerview.animators.FlipInRightYAnimator;
import jp.wasabeef.recyclerview.animators.adapters.AlphaInAnimationAdapter;
import jp.wasabeef.recyclerview.animators.adapters.ScaleInAnimationAdapter;

import static mypackage.MyDbOpenHelper.*;


public class NewsListFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

    private NewsRecyclerViewAdapter mAdapter;
    private SaveImageTask saveImageTask;
    private NewsType newsType;
    private Activity parent;

    public static NewsListFragment newInstance(NewsType newsType, Activity container) {
        NewsListFragment fragment = new NewsListFragment();
        fragment.saveImageTask = new SaveImageTask(container);
        fragment.newsType = newsType;
        fragment.parent = container;
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             final Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.recycler_view, container, false);
        ButterKnife.bind(this, view);

        final RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.my_recycler_view);
        mRecyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(view.getContext());
        mRecyclerView.setLayoutManager(mLayoutManager);

        Picasso picasso = new Picasso.Builder(parent).build();
        ContentResolver contentResolver = parent.getContentResolver();
        Cursor newsCursor;
        if (newsType == NewsType.ALL) {
            newsCursor = contentResolver.query(NewsProvider.CONTENT_URI, null, null, null, null);
        } else {
            newsCursor = contentResolver.query(SavedNewsProvider.CONTENT_URI, null, null, null, null);
        }

        mAdapter = new NewsRecyclerViewAdapter(newsCursor);
        mAdapter.setPicasso(picasso);

        AlphaInAnimationAdapter alphaAdapter = new AlphaInAnimationAdapter(mAdapter);
        ScaleInAnimationAdapter scaleAdapter = new ScaleInAnimationAdapter(alphaAdapter);
        scaleAdapter.setFirstOnly(false);
        scaleAdapter.setInterpolator(new OvershootInterpolator());
        mRecyclerView.setItemAnimator(new FlipInRightYAnimator());
        mRecyclerView.getItemAnimator().setAddDuration(300);

        mRecyclerView.setAdapter(scaleAdapter);

        ViewCompat.setElevation(view, 50);
        parent.getLoaderManager().initLoader(0, null, this);

        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                Cursor news = parent.getContentResolver().query(NewsProvider.CONTENT_URI,
                        null, null, null, null);
                if (news == null || news.getCount() == 0) {
                    insertNewsList();
                } else {
                    news.close();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                parent.getLoaderManager().restartLoader(0, null, NewsListFragment.this);
                mAdapter.notifyDataSetChanged();
                ContentResolver.requestSync(null, NewsProvider.AUTHORITY, new Bundle());
                mRecyclerView.refreshDrawableState();
                mRecyclerView.postInvalidate();
            }
        }.execute(null, null, null);


        return view;
    }

    private void insertNewsList() {
        String[] titles = {"Web", "Java", "Android"};
        Random random = new Random(Calendar.getInstance().getTimeInMillis());
        for (String title : titles) {
            int count = random.nextInt(20);
            List<News> newsList = generateDataSet(title, count);
            for (News dataObject : newsList) {
                ContentValues initialValues = new ContentValues();
                initialValues.put(NEWS_IMAGE_LINK, dataObject.getTopImageLink());
                initialValues.put(NEWS_IMAGE_PATH, dataObject.getTopImagePath());
                initialValues.put(NEWS_LINK, dataObject.getLink());
                initialValues.put(NEWS_SOURCE, dataObject.getSourceText());
                initialValues.put(NEWS_SOURCE_IMG_LINK, dataObject.getSourceImageLink());
                initialValues.put(NEWS_SOURCE_IMG_PATH, dataObject.getSourceImagePath());
                initialValues.put(NEWS_TAGS, Arrays.toString(dataObject.getTag()));
                initialValues.put(NEWS_TEXT, dataObject.getText());
                initialValues.put(NEWS_TIME, getDateTime());
                initialValues.put(NEWS_TITLE, dataObject.getTitle());
                parent.getContentResolver().insert(NewsProvider.CONTENT_URI, initialValues);
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(parent, NewsProvider.CONTENT_URI, null, null, null, null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        mAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }



    private List<News> generateDataSet(String subject, int count) {
        String title = "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...";
        String text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque porttitor nulla nec nulla fermentum, " +
                "quis imperdiet ipsum aliquet. Phasellus quis odio sit amet nulla rutrum porta. Quisque in ultrices metus." +
                " Aliquam gravida et lacus ac vestibulum.";

        String topImageLink = "http://lorempixel.com/1024/768/";
        String[] categories = {"abstract", "city", "people", "transport", "animals",
                "food", "nature", "business", "nightlife", "sports", "cats", "fashion", "technics"};
        String sourceImageLink = "http://thegg.net/wp-content/themes/Orizon/css/blue_css/images/rss-icon.png";
        String sourceText = "Random Blog";
        String link = "http://www.google.com";

        List<News> results = new ArrayList<>();
        for (int index = 0; index < count; index++) {

            int imgIndex = index % 12;

            String imgText = subject + "-card-" + index;
            String newTitle = imgText + " " + title;

            News obj = new News(newTitle);
            if (index % 2 == 0) {
                obj.setText(text);
            } else {
                obj.setTopImageLink(topImageLink + categories[imgIndex] + "/" + imgText);
            }

            if (index % 5 != 0) {
                obj.setSourceImageLink(sourceImageLink);
                obj.setSourceText(sourceText);
            }

            if (index % 7 == 0) {
                obj.setText(text);
                obj.setTopImageLink(topImageLink + categories[imgIndex] + "/" + imgText);
                obj.setSourceImageLink(sourceImageLink);
                obj.setSourceText(sourceText);
            }

            if (obj.getTopImageLink() != null && !"".equalsIgnoreCase(obj.getTopImageLink())) {
                Uri topImageUri = saveImageTask.saveImageFile(obj.getTopImageLink());
                obj.setTopImagePath(topImageUri.getPath());
            }

            if (obj.getSourceImageLink() != null && !"".equalsIgnoreCase(obj.getSourceImageLink())) {
                Uri sourceImageUri = saveImageTask.saveImageFile(obj.getSourceImageLink());
                obj.setSourceImagePath(sourceImageUri.getPath());
            }

            obj.setLink(link);
            obj.setTag(new String[] {subject});
            results.add(index, obj);
        }
        return results;
    }

    private String getDateTime() {
        SimpleDateFormat dateFormat = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss", Locale.getDefault());
        Date date = new Date();
        return dateFormat.format(date);
    }

    public enum NewsType {
        ALL,
        FAVORITE
    }
}
我只停留在需要通知回收者视图的部分 以某种方式更新自己。我实现了这个 ,但它是有效的 仅当数据库中已有数据时。它在我的工作环境中不起作用 情景


如果您有一个
ContentProvider
,并且正在使用,则在通知正确的
Uri
后,框架应再次查询数据库。如果未使用ContentProvider,则可以使用在数据库中插入新数据后广播事件。片段应注册到此事件,并手动重新查询数据库

您可以使用它向适配器发送消息以调用

您的片段是否使用
游标加载程序
从数据库加载数据?是。我的片段实现了
LoaderManager.LoaderCallbacks
,并使用CursorLoader从数据库中加载。这已经有一年多的历史了,还没有得到任何您能够接受的答案。事后来看,这是否太宽泛了,或者你能添加一个自我回答吗?我已经用我的代码更新了我的问题。你能澄清一下我应该如何修改它吗?你有一个ContentProvider吗?我已经用我的ContentProvider更新了我的问题。谢谢你的耐心。那为什么我把数据放在一个空白的数据库里不起作用呢。但如果我通过打开父活动重新创建视图,它会显示数据。但这是第一次,它从未从后台重新加载。我尝试从异步任务的后处理中使用notifyDataSetChange,但没有成功。我已经用我的代码更新了我的问题。你能澄清一下我做错了什么吗?
package mypackage.database;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public abstract class NewsProvider extends ContentProvider {

    public static final String AUTHORITY = "myapp.data.newsprovider";
    private static final String BASE_PATH = "news";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH );

    // Constant to identify the requested operation
    private static final int NEWS = 1;
    private static final int NEWS_ID = 2;
    private static final int NEWS_TAG = 3;
    private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        uriMatcher.addURI(AUTHORITY, BASE_PATH, NEWS);
        uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", NEWS_ID);
        uriMatcher.addURI(AUTHORITY, BASE_PATH + "/tag/*", NEWS_TAG);
    }

    private String tableName;
    private String basePath;
    protected SQLiteDatabase database;

    public NewsProvider() {
        this.tableName = TABLE_NEWS;
        this.basePath = BASE_PATH;
    }

    @Override
    public boolean onCreate() {
        MyDbOpenHelper helper = new MyDbOpenHelper(getContext());
        database = helper.getWritableDatabase();
        return true;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        if (uriMatcher.match(uri) == NEWS_ID) {
            selection = NEWS_ID + "=" + uri.getLastPathSegment();
        }

        if (uriMatcher.match(uri) == NEWS_TAG) {
            selection = NEWS_TAGS + " like %'" + uri.getLastPathSegment() + "'%";
        }

        return database.query(TABLE_NEWS, NEWS_ALL_COLUMNS,
                selection, null, null, null, NEWS_TIME + " DESC");
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long id = database.insert(tableName, null, values);
        Uri newUri = Uri.parse(basePath + "/" + id);
        getContext().getContentResolver().notifyChange(newUri, null);
        return newUri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return database.delete(tableName, selection, selectionArgs);
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return database.update(tableName, values, selection, selectionArgs);
    }
}