java - RecyclerView 没有更新 OnPostExecute() 上的项目

标签 java android multithreading android-recyclerview jsoup

提前向这里的所有人问好。

在寻找问题的解决方案时,我一直在问题和疯狂之间徘徊,我已经投入了更多的时间来解决我的困境,现在我需要该领域最有知识的人来帮助我。

正如我在下面详述的那样,我正在做的或至少试图做的是在收集保存在 DB 中的某些数据时更新 RecyclerView > 和 元素列表

我要在 RecyclerView 中绘制的数据,我通过以下方式获得它,使用 rssparser 我首先获得一个链接列表,稍后使用Jsoup,我得到新闻的图片和文本。

碰巧这些使用网络交互的函数必须在 threads 内部调用,而不是 UI 的线程,好吧我相信我已经像多线程一样在那里创建了,好在异步任务中获取数据的函数。

我需要做的另一件事是在线程处理完成之前保持此 View 中的 progress bubble。理想情况下它会实时工作,我已经做到了,但是通过将每个新元素添加到列表并通知适配器新插入的项目对我来说不起作用。

当任务处理结束,线程完成他们的工作时,我也没有用 adapter.notifyDatasetChanged() 更新 RecyclerView,我不知道还有什么可以尝试的,也许我有一些算法错误。

下面是我的代码,我为我的踪迹道歉,确保我留下了一些不必要的代码或评论。

fragment :

public class ViewerNewsFragment1 extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

private static final String ARG_COLUMN_COUNT = "column-count";

private int mColumnCount = 1;
private OnListFragmentInteractionListener mListener;
private static final String ARG_PARAM1 = "id";


// TODO: Rename and change types of parameters
private Integer mParam1;
private String finalUrl;
private ViewerNewsRecyclerViewAdapter adapter;
private SwipeRefreshLayout swipeView;
private TextView connectionError;
private int imageHolder;
private NewsHelper newsHelper;



private String SENT_ = "SMS_SENT_SUSCRIPTION_";
private String DELIVERED_ = "SMSDELIVERED_SUSCRIPTION_";
private BroadcastReceiver sendBroadcastReceiver;
private BroadcastReceiver deliveryBroadcastReceiver;

List<News> news = new ArrayList<>();

private boolean flag =  false;
OkHttpClient client;

private boolean isAlreadyRefresh;


public ViewerNewsFragment1() {
}


public static ViewerNewsFragment1 newInstance(int columnCount, Integer id) {
    ViewerNewsFragment1 fragment = new ViewerNewsFragment1();
    Bundle args = new Bundle();
    args.putInt(ARG_COLUMN_COUNT, columnCount);
    args.putInt(ARG_PARAM1, id);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    newsHelper = new NewsHelper(getActivity());
    if (getArguments() != null) {
        mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
        mParam1 = getArguments().getInt(ARG_PARAM1);
        DummyContent.DummyItem item = DummyContent.ITEMS.get(new Integer(mParam1) - 1);
        finalUrl = item.url;
        imageHolder = item.smallimage;

    }
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

}

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_viewer_news_list, container, false);
    // Set the adapter

    Context context = view.getContext();
    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_news);
    recyclerView.setLayoutManager(new LinearLayoutManager(context));
    adapter = new ViewerNewsRecyclerViewAdapter(news, mListener, imageHolder, newsHelper.getNewsDao());
    recyclerView.setAdapter(adapter);
    swipeView = (SwipeRefreshLayout) view.findViewById(R.id.swipe);
    swipeView.setOnRefreshListener(this);
    swipeView.setProgressViewOffset(false, 0,
            (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics()));
    connectionError = (TextView) view.findViewById(R.id.connection_error);
    setRetainInstance(true);

    Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.acerca_toolbar);
    toolbar.setBackgroundColor(Color.parseColor("#f2f2f2"));
    ImageView iv =  (ImageView) toolbar.findViewById(R.id.iconToShow);
    toolbar.getContext().setTheme(R.style.AppTheme2);
    int img_bar = R.drawable.appbar_cubadebate;
    SharedPreferences preferences = ((ViewerActivity) mListener).getSharedPreferences("client_data", Context.MODE_WORLD_WRITEABLE);
    SharedPreferences.Editor ed = preferences.edit();
    if (mParam1.equals(1)) {
        ed.putInt("cubadebate", 0);
        ed.commit();
        img_bar = R.drawable.appbar_cubadebate;
    } else if (mParam1.equals(2)) {
        ed.putInt("granma", 0);
        ed.commit();
        img_bar = R.drawable.appbar_granma;
    } else if (mParam1.equals(3)) {
        ed.putInt("prela", 0);
        ed.commit();
        img_bar = R.drawable.appbar_pl;
    }
    iv.setImageResource(img_bar);
    isAlreadyRefresh = false;
    setHasOptionsMenu(true);


    Dao<News, Integer> dao = newsHelper.getNewsDao();
    try {
        QueryBuilder<News, Integer> builder = newsHelper.getNewsDao().queryBuilder();
        builder.where().eq("author", mParam1.toString());
        builder.limit(20);
        builder.orderBy("newsDate", false); // true for ascending, false for descending
        news = dao.query(builder.prepare());

    }catch (Exception e){
        e.printStackTrace();
    }


    adapter.setmValues(news);
    adapter.notifyDataSetChanged();

    return view;
}


private void fetchNews() {
    fetchInternalNews();
    if (isNetworkAvailable()) {

        Cache cache = new Cache(getContext().getCacheDir(), Integer.MAX_VALUE);
        client = new OkHttpClient.Builder()
                .addNetworkInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Response originalResponse = chain.proceed(chain.request());
                        return originalResponse.newBuilder().header("Cache-Control", "max-age=" + (60 * 60 * 24 * 365)).build();
                    }
                })
                .cache(cache)
                .build();

        Parser parser = new Parser();
        parser.execute(finalUrl);

        parser.onFinish(new Parser.OnTaskCompleted() {

            @Override
            public void onTaskCompleted(final ArrayList<Article> list) {

                new LongOperation().execute(list);
            }

            @Override
            public void onError() {
                if (getActivity() != null)
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            swipeView.setRefreshing(false);
                            connectionError.setVisibility(View.VISIBLE);
                            isAlreadyRefresh = false;
                     }
                });
            }
        });
    } else {
        swipeView.setRefreshing(false);
        Toast.makeText(getContext(), "No tiene conexión a Internet. Active la Wi-Fi o los datos móviles, y vuelva a intentarlo.", Toast.LENGTH_LONG).show();
    }

}

private class LongOperation extends AsyncTask<List<Article>, Void, String> {

    @Override
    protected String doInBackground(List<Article>... lists) {
        swipeView.setRefreshing(true);
        GoScrapp(lists[0]);
        return "Executed";
    }

    @Override
    protected void onPostExecute(String result) {
       adapter.notifyDataSetChanged();
       isAlreadyRefresh = true;
       swipeView.setRefreshing(false);
    }
}
public void GoScrapp(List<Article> list){

    Dao<News, Integer> dao = newsHelper.getNewsDao();
    News t = new News();
    List<News> news_list = new ArrayList<>();
    try {
        QueryBuilder<News, Integer> builder = newsHelper.getNewsDao().queryBuilder();
        builder.where().eq("author", mParam1.toString());
        builder.limit(20);
        builder.orderBy("newsDate", false); // true for ascending, false for descending
        news_list = dao.query(builder.prepare());

    }catch (Exception e){
        e.printStackTrace();
    }

    boolean esta = false;
    for (Article article : list) {
        if(!news_list.isEmpty())
            for (News item : news_list) {
                if(item.getLink().equals(article.getLink())){
                    esta = true;
                }
            }else esta = false;

        if(!esta) {
            Foo foo = new Foo(article);
            Thread th = new Thread(foo);
            try {
                th.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

private void fetchInternalNews() {       
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnListFragmentInteractionListener) {
        mListener = (OnListFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnListFragmentInteractionListener");
    }
}

@Override
public void onResume() {
    super.onResume();
    onRefresh();
    //Todo:Puse este valor en true, estaba en false
    isAlreadyRefresh = true;
}

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

@Override
public void onRefresh() {
    if (!isAlreadyRefresh) {
        swipeView.setRefreshing(true);
        swipeView.postDelayed(new Runnable() {
            @Override
            public void run() {
                fetchNews();
                isAlreadyRefresh = true;
                adapter.setmValues(news);
            }
        }, 1000);
    } else
        swipeView.setRefreshing(false);
}


public interface OnListFragmentInteractionListener {

    void onListFragmentInteraction(Integer id);
}

private boolean CanSuscribe(){
    NewsHelper helper = new NewsHelper(getContext());
    SuscriptionRequest sr_object;
    Date today = new Date();
    boolean result;

    try {
        if(!helper.getSuscriptionRequestDao().queryForEq(SuscriptionRequest.FUENTE, mParam1).isEmpty())
        {
            sr_object = helper.getSuscriptionRequestDao().queryForEq(SuscriptionRequest.FUENTE, mParam1).get(0);
            //get the date of usscription
            Date date = sr_object.getFecha();
            Calendar calendar = new GregorianCalendar(/* remember about timezone! */);
            calendar.setTime(date);
            calendar.add(Calendar.DATE, 30);
            date = calendar.getTime();
            result = today.after(date);
        } else {
            result = true;
        }
    }catch (SQLException e) {
        Log.e("ERROR Saving SR", e.getMessage());
        result =  false;
    }
    return result;
}

private void SaveSuscriptionRequest(){

    NewsHelper helper = new NewsHelper(getContext());
    SuscriptionRequest sr = new SuscriptionRequest();

    try{
        if(!helper.getSuscriptionRequestDao().queryForEq(SuscriptionRequest.FUENTE, mParam1).isEmpty()) {
            sr.setFecha(new Date());
            sr.setFuente(mParam1);
            helper.getSuscriptionRequestDao().create(sr);
        } else {
            sr = helper.getSuscriptionRequestDao().queryForEq(SuscriptionRequest.FUENTE, mParam1).get(0);
            sr.setFecha(new Date());
            helper.getSuscriptionRequestDao().update(sr);
        }


    } catch (SQLException e) {
        Log.e("ERROR Saving SR", e.getMessage());
    }
}

public void sendMessage(String phoneNumber, String message) {
    final Activity mContext = (Activity) mListener;
    PendingIntent sentPI = PendingIntent.getBroadcast(mContext, 0, new Intent(SENT_), 0);
    PendingIntent deliveredPI = PendingIntent.getBroadcast(mContext, 0, new Intent(DELIVERED_), 0);
    SmsManager sms = SmsManager.getDefault();
    sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
}

@Override
public void onPause() {
    super.onPause();
    if(flag) {
        myOnDestroy();
    }
}

public class Foo implements Runnable {
    private volatile String value;
    private String url;
    private Article article;




    public Foo(Article article){
        this.url = article.getLink();
        this.article = article;
    }

    @Override
    public void run() {
        final StringBuilder builder = new StringBuilder();

        OkHttp3Downloader okHttpDownloader = new OkHttp3Downloader(client);
        Picasso picasso = new Picasso.Builder(getContext()).downloader(okHttpDownloader).build();

        try {
            Document doc = Jsoup.connect(url).get();
            Elements links = new Elements();
            Elements img = new Elements();
            String img_url = "";

            switch (mParam1){
                case 1:
                    links = doc.select("div[class=note_content] > p");
                    img = doc.select("div[id^=\"attachment_\"] > img");
                    if(!img.isEmpty())
                    {
                        img_url = img.first().attr("srcset").split(" ")[0];
                        if(img_url.isEmpty())
                            img_url = img.first().attr("src");
                        if(!img_url.isEmpty()) picasso.with(getContext()).load(img_url).fetch();
                    }
                    break;
                case 2:
                    links = doc.select("div[class=story-body-text story-content] > p");
                    img = doc.select("div[class=image] > img");
                    if(!img.isEmpty()){
                        img_url = "http://www.granma.cu"+img.first().attr("src");
                        Log.e("URL", img_url);
                        if(!img_url.isEmpty()) picasso.with(getContext()).load(img_url).fetch();
                    }
                    break;
                case 3:
                    links = doc.select("div[class=fullNewsFulltext]");
                    img = doc.select("div[class=fullNewsIntrotext] img");
                    if(!img.isEmpty()){
                        img_url = "http://prensa-latina.cu"+img.first().attr("src");
                        Log.e("URL", img_url);
                        if(!img_url.isEmpty()) picasso.with(getContext()).load(img_url).fetch();
                    }
                    break;
            }
            for (Element link : links) {
                builder.append(link.text()).append("\n");
            }
            value = article.getLink();

            Dao<News, Integer> dao = newsHelper.getNewsDao();
            News t = new News();
            String author = "";
            t.setTitle(article.getTitle());
            t.setAuthor(mParam1.toString());
            t.setDescription(article.getDescription());
            t.setLink(article.getLink());
            t.setCompleteDescription(builder.toString());
            t.setImage(article.getImage());
            t.setImage_link(img_url);





            if (article.getPubDate() != null)
                t.setNewsDate(article.getPubDate());
            else {
                final SimpleDateFormat sf = new SimpleDateFormat("dd/MM/yyyy hh:mm");
                try {
                    t.setNewsDate(sf.parse(sf.format(new Date())));
                } catch (Exception e) {
                    Log.e("ERROR FECHA", e.getMessage());
                }
            }
            try {
                List<News> existing = dao.queryForEq("title", t.getTitle());
                if (existing.size() == 0) {
                    dao.create(t);
                    news.add(t);
                    Log.e("ERROR FECHA", "ADD"+t.getTitle());

                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // Stuff that updates the UI
                            adapter.notifyItemInserted(news.size() - 1);


//             adapter.notifyDataSetChanged();
   //                                swipeView.setRefreshing(true);
                        }
                    });


//                        adapter.notifyDataSetChanged();
                }
            } catch (SQLException e) {
                Log.e("ERROR", e.getMessage());
            }

        } catch (IOException e) {
            builder.append("Error : ").append(e.getMessage()).append("\n");
        }
    }


    public String getValue() {
        return value;

    }
}

public void myOnDestroy(){
    final Activity mContext = (Activity) mListener;
    mContext.unregisterReceiver(sendBroadcastReceiver);
    mContext.unregisterReceiver(deliveryBroadcastReceiver);
}

}

最佳答案

除了 adityakamble49 的回答。问题可能出在 GoScrapp 函数内部:

 if(!esta) {
        Foo foo = new Foo(article);
        Thread th = new Thread(foo);
        try {
            th.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

您正在 doInBackground() 中启动一个新线程来处理数据并更新数据库,因此在线程将数据插入数据库之前执行 onPostExecute()。

关于java - RecyclerView 没有更新 OnPostExecute() 上的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51387926/

相关文章:

java - 在没有 Cascade Persist 的情况下使用 JPA

android - Android同步失败:找不到项目

java - Android 按距离重新排序适配器

python - 如何编写脚本在多核机器上有效运行多进程

java - JPA VS JDBC - 2 个问题

java - 如何使用 sleep 时间在java中生成超过1000个事件/秒

java - 使用 FIDO UAF 进行指纹扫描以用于移动应用程序

C# 如何让线程等待两个手动重置事件中的任何一个?

java - MySQL 和 Java 中的多线程编程

java - Quartz——在云服务器上踢多线程