Как обновить элементы RecyclerView с помощью AsyncTask - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь обновить элементы recyclerview из данных в базе данных SQLite, которая, в свою очередь, время от времени обновляется данными, извлекаемыми из API.

У меня есть TabLayout, которые содержат три fragments.

Теперь в одном фрагменте я показываю игры, в которые играют пользователи, в виде recyclerView. Каждый элемент recyclerView содержит имя пользователя, его высокий балл и номер. других пользователей, которые побили его высокий балл.

Теперь во фрагменте я вызываю API для обновления базы данных внутри AsyncTask, а затем снова использую ту же базу данных в RecyclerView классе адаптеров для извлечения данных в другом AsyncTask. AsyncTask периодически вызывается с использованием TimerTask и обработчика.

 @TargetApi(Build.VERSION_CODES.CUPCAKE)
    @RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
    public class PerformBackgroundTask extends AsyncTask<String, Void, String>{

        @Override
        protected String doInBackground(String... gameID) {

            try{

                SQLiteDatabase challengeDatabase = mContext.openOrCreateDatabase("Challenge", Context.MODE_PRIVATE, null);

                challengeDatabase.execSQL("CREATE TABLE IF NOT EXISTS DISPLAY_MESSAGE (gameID VARCHAR, highestScorer VARCHAR, count INT)");
                Cursor d = challengeDatabase.rawQuery("SELECT * FROM DISPLAY_MESSAGE WHERE gameID", null);

                int gameCode = d.getColumnIndex("gameID");
                int highestScorer = d.getColumnIndex("highestScorer");
                int count = d.getColumnIndex("count");

                d.moveToFirst();

                while(d!=null&&d.getCount()>0){
                    if((d.getString(gameCode)).equals(gameID)){

                        int k = Integer.parseInt(d.getString(count));

                        if(k>0)
                        {
                            return d.getString(highestScorer) + " and " + k + " others have beaten your highscore.";
                        }else if(k==0){
                            return d.getString(highestScorer) + " has beaten your highscore.";
                        }
                        else{
                            return "Yay! you have beaten all your opponents!";
                        }
                    }

                    d.moveToNext();
                }

                challengeDatabase.close();
            }catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }
    }


    public GridAdapterChallenge(Context c, List<CardContainer> listCards, Vector<Object> cardDetails, String sname) {
        //selectedCards = new HashSet<Integer>();
        inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mContext = c;
        this.listCards = listCards;
        this.sname = sname;
        cards = cardDetails;
        //notifyDataSetChanged();

    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private int viewType;
        private ImageView imageView;
        private Button increaseScore, challengeFriend;
        private TextView challengeDetails, points, name, challengeCode;
        private ImageView nativeAdIcon;
        private TextView nativeAdTitle;
        private TextView nativeAdBody;
        private MediaView nativeAdMedia;
        private TextView nativeAdSocialContext;
        private Button nativeAdCallToAction;
        private ProgressBar detailProgress;


        public ViewHolder(@NonNull View itemView, int viewType) {
            super(itemView);

            view = itemView;
            this.viewType = viewType;
            if (viewType == 1) {
                this.imageView = (ImageView) itemView.findViewById(R.id.thumb);
                this.name = (TextView) itemView.findViewById(R.id.gameName);
                this.challengeCode = itemView.findViewById(R.id.challengeCode);
                this.points = itemView.findViewById(R.id.points);
                this.challengeDetails = itemView.findViewById(R.id.challengeDetail);
                this.increaseScore = itemView.findViewById(R.id.increaseScore);
                this.challengeFriend = itemView.findViewById(R.id.challengeFriend);
                this.challengeDetails = itemView.findViewById(R.id.challengeDetail);
                this.detailProgress = itemView.findViewById(R.id.detailProgressBar);
            } else {
                this.nativeAdIcon = (ImageView) itemView.findViewById(R.id.native_ad_icon);
                this.nativeAdTitle = (TextView) itemView.findViewById(R.id.native_ad_title);
                this.nativeAdBody = (TextView) itemView.findViewById(R.id.native_ad_body);
                this.nativeAdMedia = (MediaView) itemView.findViewById(R.id.native_ad_media);
                this.nativeAdSocialContext = (TextView) itemView.findViewById(R.id.native_ad_social_context);
                this.nativeAdCallToAction = (Button) itemView.findViewById(R.id.native_ad_call_to_action);
            }
        }
    }

    public void updateDetails(final TextView challengeDetails, final String gameId) {
        final Handler handler;
        handler = new Handler();
        Timer timer = new Timer();
        doAsynchronousTask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                        try {
                            PerformBackgroundTask performBackgroundTask = new PerformBackgroundTask();
                            challengeDetails.setText((CharSequence) performBackgroundTask.execute(gameId));

                        } catch (Exception e) {
                        }
                    }
                });
            }
        };
        timer.schedule(doAsynchronousTask, 4000, 5000); //execute in every 1000 ms
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder viewHolder, final int i) {
        if (viewHolder.viewType == 0) {
            if (adList != null && adList.size() > (i+1)/5 - 1 && adList.get((i+1)/5 - 1) != null) {
                NativeAd ad = adList.get((i+1)/5 - 1);
                viewHolder.nativeAdSocialContext.setText(ad.getAdSocialContext());
                viewHolder.nativeAdCallToAction.setText(ad.getAdCallToAction());
                viewHolder.nativeAdCallToAction.setVisibility(View.VISIBLE);
                viewHolder.nativeAdTitle.setText(ad.getAdHeadline());
                viewHolder.nativeAdBody.setText(ad.getAdBodyText());
                ad.registerViewForInteraction(viewHolder.itemView, viewHolder.nativeAdMedia, viewHolder.nativeAdIcon, Arrays.asList(viewHolder.nativeAdCallToAction, viewHolder.nativeAdMedia));
                NativeAd.Image adCoverImage = ad.getAdCoverImage();
                int bannerWidth = adCoverImage.getWidth();
                int bannerHeight = adCoverImage.getHeight();
                DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
                int mediaWidth = viewHolder.itemView.getWidth() > 0 ? viewHolder.itemView.getWidth() : metrics.widthPixels;
                viewHolder.nativeAdMedia.setLayoutParams(new LinearLayout.LayoutParams(mediaWidth, Math.min(
                        (int) (((double) mediaWidth / (double) bannerWidth) * bannerHeight), metrics.heightPixels / 3)));
                ad.registerViewForInteraction(viewHolder.itemView, viewHolder.nativeAdMedia, Arrays.asList(viewHolder.nativeAdCallToAction, viewHolder.nativeAdMedia));
                ad.registerViewForInteraction(viewHolder.itemView, viewHolder.nativeAdMedia);
            }
        } else{

            viewHolder.name.setText(((CardContainer)cards.get(i)).name);
            challengeCode = getChallengeCode(i);
            viewHolder.challengeCode.setText(challengeCode);
            DisplayMetrics displayMetrics = new DisplayMetrics();
            ((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

            if(getHighScore(((CardContainer)cards.get(i)).gameId)>0){
                PerformBackgroundTask performBackgroundTask = new PerformBackgroundTask();
                viewHolder.challengeDetails.setText(performBackgroundTask.execute(gameId).toString());
                //updateDetails(viewHolder.challengeDetails, ((CardContainer)cards.get(i)).gameId);
                }
            else{
                viewHolder.challengeDetails.setText("Press Increase Score To Play the Game");
            }
            viewHolder.detailProgress.setVisibility(View.GONE);


            int width = displayMetrics.widthPixels;
            try {
                final String uri = ((CardContainer) cards.get(i)).imageurl;
                if (uri != null) {
                    Picasso.get().load(uri)
                            .placeholder(R.mipmap.place)
                            .error(R.mipmap.place)
                            .resize(width / 2, width / 2)
                            .centerCrop()
                            .into(viewHolder.imageView);

                }
            }
            catch (Exception e){
                final String uri = null;
            }

            viewHolder.points.setText(String.valueOf(getHighScore(((CardContainer)cards.get(i)).gameId)));

            viewHolder.increaseScore.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    if (((CardContainer) cards.get(i)).link.contains("play.google.com")) {
                        openAppRating(mContext,((CardContainer) cards.get(i)).link.split("id=", 2)[1]);
                    }
                    else{
                        name = ((CardContainer) cards.get(i)).name;
                        link = ((CardContainer) cards.get(i)).link;
                        imageurl = ((CardContainer) cards.get(i)).imageurl;
                        type = ((CardContainer) cards.get(i)).type;
                        packageName = ((CardContainer) cards.get(i)).packageName;
                        gameId = ((CardContainer)cards.get(i)).gameId;

                        challengeNames.add(name);

                        updateDatabase(name, gameId, Config.uid+"@"+gameId, 0, viewHolder.points);

                        //String gameName, String gameId, String mychCode, int myHighScore
                    }
                }
            });
            viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                String name = ((CardContainer) cards.get(i)).name;
                String link = ((CardContainer) cards.get(i)).link;
                String imageurl = ((CardContainer) cards.get(i)).imageurl;
                String type = ((CardContainer) cards.get(i)).type;
                String packageName = ((CardContainer) cards.get(i)).packageName;
                Bitmap bitmap = null;
                Integer xyz = android.os.Build.VERSION.SDK_INT;
                @Override
                public boolean onLongClick(View view) {

                    bitmap = ((BitmapDrawable) viewHolder.imageView.getDrawable()).getBitmap();
                    if (sname.equals("fav")) {
                        //    Toast.makeText(mContext, "in fav", Toast.LENGTH_SHORT).show();
                        final Dialog dialog = new Dialog(mContext);
                        dialog.setContentView(R.layout.custom_dialog);
                        TextView dialogText=dialog.findViewById(R.id.txt_dia);
                        dialogText.setText("Do you want to remove "+name+" from your favorites?");
                        dialog.show();
                        Button yes_button = (Button) dialog.findViewById(R.id.btn_yes);
                        yes_button.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                favf = new FavFunction(mContext);
                                int resultFav=favf.removeFromFavorite(link);
                                if (resultFav>=0){
                                    cards.remove(resultFav);

                                    notifyDataSetChanged();
                                }
                                dialog.dismiss();
                            }
                        });
                        Button no_button = (Button) dialog.findViewById(R.id.btn_no);
                        no_button.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                dialog.dismiss();
                            }
                        });
                        return true;
                    }
                    else{
                        final Dialog dialog = new Dialog(mContext);
                        dialog.setContentView(R.layout.custom_dialog);
                        TextView dialogText=dialog.findViewById(R.id.txt_dia);
                        dialogText.setText("Adding "+name+" to favorites... Do you also want to create it's homescreen shortcut?");
                        dialog.show();
                        Button yes_button = (Button) dialog.findViewById(R.id.btn_yes);
                        yes_button.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                favf = new FavFunction(mContext);
                                Boolean favstatus=favf.addToFavorite(imageurl, link ,name,type,packageName);
                                favf.addShortcut(name, link , imageurl,type,packageName,bitmap);
                                if(favstatus){
                                    ((Activity) mContext).recreate();
                                }
                                dialog.dismiss();
                            }
                        });
                        Button no_button = (Button) dialog.findViewById(R.id.btn_no);
                        no_button.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                favf = new FavFunction(mContext);
                                Boolean favstatus=favf.addToFavorite(imageurl, link, name,type,packageName);
                                if(favstatus){
                                    ((Activity) mContext).recreate();
                                }
                                dialog.dismiss();
                            }
                        });
                        return true;
                    }
                }
            });

            viewHolder.challengeFriend.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent sendIntent = new Intent();
                    sendIntent.setAction(Intent.ACTION_SEND);
                    sendIntent.putExtra(Intent.EXTRA_TEXT, "Hey! I challenge you to beat my highscore " + getHighScore(gameId) + " in this awesome game. Enter my challenge code " + challengeCode + " in the \"Challenges\" Tab of 101 Game Store App. You can download the app from bit.ly/101gamestore");
                    sendIntent.setType("text/plain");
                    mContext.startActivity(sendIntent);
                }
            });
        }
    }

хочу обновить нет. высокого балла внутри каждого элемента recyclerView. Однако происходит то, что пользовательский интерфейс зависает, как только начинается TimerTask. Данные извлекаются успешно. Любое решение, подходящее лучше моего, будет оценено.

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Для обновления вашего адаптера вы должны сделать это в главном потоке. AsyncTask предоставляет метод onPostExecute.

Не заменяйте адаптер, вместо этого вы должны заменить данные в адаптере.

class MyAsyncTask extends AsyncTask<Void, Void, List<String>> {
    MyAdapter myAdapter;
    ArrayList<String> values = new ArrayList<>();

    public MyAsyncTask(MyAdapter adapter) {
        this.myAdapter = myAdapter;
    }

    @Override
    protected List<String> doInBackground(String... params) {
        ArrayList<String> result = new ArrayList<>();
        // long operation, for example: get results from url
        return result;
    }

    @Override
    protected void onPostExecute(List<String> list) {
        myAdapter.setNewList(list);
    }
}

class MyAdapter {

    private List<String> list;

    ............

    void setNewList(List<String> list) {
        this.list = list;
        notifyDataSetChanged();
    }

    ............
}
0 голосов
/ 05 января 2019

Просто посмотрите здесь ....

 class MyAsyncTask extends AsyncTask<String, Void, String> {
    Context mContext;
    ArrayList<String> values= new ArrayList<String>();

    public MyAsyncTask(Context context) {
        mContext = context;
    }

    @Override
    protected String doInBackground(String... params) {
        // do your all database operation here and try to stroe in arraylist
        values.add("Data comes from database");
        return "";

    }

    @Override
    protected void onPostExecute(String list) {
     // Do your View update here.
    // All your Recycle View here
    yourRecycleView.setAdapter(new MyAdapter(context,values))
    }
}

Примечание: - В AsynTask выполняйте все операции связывания в методе onPreExecute(), выполняйте всю работу с базой данных или длинными потоками в методе doInBackground() (например, извлекайте данные из базы данных, загружайте файлы или загружайте файлы и т. Д.) И обновляйте свои представления. в onPostExecute() метод.

Как обновить элементы RecyclerView с помощью AsyncTask?

Следуйте тому же процессу, чтобы получить данные в методе doInBackground() и уведомить свой адаптер в методе onPostExecute(). Сделайте эту операцию в другой AsynTask

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...