【问题标题】:AsyncTaskLoader again initialized whenever app is minimized and resumed每当应用程序最小化和恢复时,AsyncTaskLoader 都会再次初始化
【发布时间】:2017-10-10 06:22:20
【问题描述】:

当应用程序启动时,它工作正常,我可以向左和向右滑动,没有任何问题。但是,一旦应用程序被最小化并恢复,它就会再次调用加载程序并再次获取数据,这会导致底部不再有点。 ps: 加载器被再次调用,因为点在onLoadfinshed。

首次发布 Intial launch

最小化并恢复应用后 after resuming

package com.example.kaushal.slider;

/**
 * Created by kaushal on 25-09-2017.
 */

import android.app.LoaderManager;
import android.content.Loader;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.LinearLayout;

import java.util.List;


public class MainActivity1 extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<video1>> {
    customadap adap;
    ViewPager viewPager;
    private List<video1> videolist;
    int LoaderId = 1;
    LinearLayout slidedotepanel;
    int dotscount;
    ImageView[] dots;
    String jsonurl = "";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main1);
        viewPager =(ViewPager)findViewById(R.id.viewpager);
        slidedotepanel = (LinearLayout)findViewById(R.id.SliderDots);
        LoaderManager lm = getLoaderManager();
        lm.initLoader(LoaderId,null,this);
    }

    @Override
    public Loader<List<video1>> onCreateLoader(int i, Bundle bundle) {
        return new videoLoader1(this,jsonurl);
    }

    @Override
    public void onLoadFinished(Loader<List<video1>> loader, List<video1> videos) {
        adap = new customadap(videos,this);
        viewPager.setAdapter(adap);
        dotscount = adap.getCount();
        dots = new ImageView[dotscount];
        for(int i = 0;i<dotscount;i++) {
            dots[i] = new ImageView(this);
            dots[i].setImageDrawable(ContextCompat.getDrawable(this, R.drawable.nonactive_dot));
            LinearLayout.LayoutParams layout_linear = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);

            layout_linear.setMargins(8, 0, 8, 0);
            slidedotepanel.addView(dots[i], layout_linear);
        }
            dots[0].setImageDrawable(ContextCompat.getDrawable(this,R.drawable.active_dot));
            viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

                }

                @Override
                public void onPageSelected(int position) {
                    for(int i =0; i<dotscount;i++){
                        dots[i].setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.nonactive_dot));
                    }
                    dots[position].setImageDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.active_dot));
                }

                @Override
                public void onPageScrollStateChanged(int state) {

                }
            });
        }


    @Override
    public void onLoaderReset(Loader<List<video1>> loader) {

    }
/*
    public void getlib(){
        StringRequest stringRequest = new StringRequest(jsonurl, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                JSONArray jsonArray = new JSONArray(response);
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            JSONArray jarray = jsonObject.getJSONArray("videolist");

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

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
    }*/
}

更新:目前我正在通过在最后一行删除 LoadFinished 上的加载程序来处理它,它工作正常,但无法处理方向更改,任何更好的方法表示赞赏。

【问题讨论】:

  • 我不知道为什么人们对一个问题投反对票...如果其中有问题...他们应该解释而不是投反对票...
  • 在您恢复您的应用程序时清除您的数据。
  • @umeshvashisth 但这会导致再次调用 URL,可能不是最佳解决方案。
  • @SanjayMajoka 完全同意你的看法 :)

标签: android android-fragmentactivity viewpagerindicator asynctaskloader


【解决方案1】:

在 Activity 的 onCreate 中,我们应该检查负载管理器是否已经存在现有线程。如果是这样,我们不应该调用 initLoader。我提供了一个如何使用 AsyncTaskLoader 的简单示例。

import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;

import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Integer> {
    private static final String TAG = MainActivity.class.getSimpleName();
    private static final int TASK_LOADER_ID = 10;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate.  Entered function.");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LoaderManager loaderManager = getSupportLoaderManager();
        Loader<Integer> myLoader = loaderManager.getLoader(TASK_LOADER_ID);
        if (myLoader != null && MyAsyncTask.isRunning()) {
            Log.d(TAG, "onCreate --> Existing loader exists and is running.  Re-using it.");
            // We use initLoader instead of restartLoader as callbacks
            //   must be replaced with those from this new activity
            loaderManager.initLoader(TASK_LOADER_ID, null, this);
            MyAsyncTask.setActivity(new WeakReference<>(this));
            showProcess( true);
        } else {
            Log.d(TAG, "onCreate --> Loader is not active.");
            showProcess( false);
        }
    }

    private void showProcess(boolean pShowProcess) {
        SeekBar seekBar = (SeekBar) findViewById(R.id.sb_progress);
        Button btnStart = (Button) findViewById(R.id.btn_start);
        Button btnCancel = (Button) findViewById(R.id.btn_cancel);
        if (pShowProcess) {
            seekBar.setVisibility(View.VISIBLE);
            btnStart.setEnabled(false);
            btnCancel.setEnabled(true);
        }
        else {
            seekBar.setVisibility(View.INVISIBLE);
            seekBar.setProgress(0);
            btnStart.setEnabled(true);
            btnCancel.setEnabled(false);
        }
    }

    public void clickStart(View view) {
        LoaderManager loaderManager = getSupportLoaderManager();
        // Restart existing loader if it exists, otherwise a new one (initLoader) is auto created
        loaderManager.restartLoader(TASK_LOADER_ID, null, this);
    }

    // A graceful attempt to stop the loader
    public void clickCancel(View view) {
        Loader<Integer> myLoader = getSupportLoaderManager().getLoader(TASK_LOADER_ID);
        if (myLoader != null) {
            MyAsyncTask.cancelled(true);
        }
    }

    @Override
    public Loader<Integer> onCreateLoader(int pID, Bundle pArgs) {
        Log.d(TAG, "onCreateLoader.  Entered function.");
        showProcess(true);
        return new MyAsyncTask(this);
    }

    @Override
    public void onLoadFinished(Loader<Integer> pLoader, Integer pResult) {
        Log.d(TAG, "onLoadFinished --> Number of items processed = " + pResult);
        showProcess( false);
        getLoaderManager().destroyLoader(TASK_LOADER_ID);
    }

    @Override
    public void onLoaderReset(Loader<Integer> pLoader) { }

    private static class MyAsyncTask extends AsyncTaskLoader<Integer> {
        private final static int SLEEP_TIME = 10 * 10;       // 100 milliseconds
        static WeakReference<MainActivity> aActivity;
        private static boolean isRunning = false, cancelled = true;
        private Integer aResult;        // Holds the results once the task is finished or cancelled

        MyAsyncTask(MainActivity pActivity) {
            super(pActivity);
            aActivity = new WeakReference<>(pActivity);
        }

        synchronized static void setActivity(WeakReference<MainActivity> pActivity) {
            aActivity = pActivity;
        }

        synchronized static void cancelled(boolean pCancelled) {
            cancelled = pCancelled;
        }

        static boolean isRunning() {
            return isRunning;
        }

        @Override
        protected void onStartLoading() {
            Log.d(TAG, "onStartLoading.  Entered function.    cancelled = " + cancelled);
            super.onStartLoading();
            if (aResult != null) {
                deliverResult(aResult);
                return;
            }
            if (!isRunning) {   // Don't start a new process unless explicitly initiated by clickStart
                Log.d(TAG, "onStartLoading --> No existing process running, so we can start a new one.");
                forceLoad();
            }
        }

        @Override
        public Integer loadInBackground() {
            Log.d(TAG, "loadInBackground.  Entered function.");
            isRunning = true;
            cancelled = false;
            int i;
            for (i = 1; i < 100 && !cancelled; i++) {
                try {
                    Thread.sleep(SLEEP_TIME);
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }
                if (aActivity.get() != null) {
                    SeekBar seekBar = (SeekBar) aActivity.get().findViewById(R.id.sb_progress);
                    seekBar.setProgress(i);
                }
                if (i % 15 == 0) {
                    Log.d(TAG, "Process running with i = " + i);
                }
            }
            isRunning = false;
            aResult = i;
            return aResult;
        }
    }
}

activity_main.xml 如下所示。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.snoopy.loadertest.MainActivity">

    <SeekBar
        android:id="@+id/sb_progress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="clickStart"
        android:text="Start Process"
        app:layout_constraintBottom_toTopOf="@id/sb_progress"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

单击“开始按钮”时,它会使 SeekBar 可见并在单独的线程中启动 AsyncTaskLoader。在任务运行时,您可以旋转设备并将其发送到后台。在重新启动应用程序时,onCreate 检查任务是否存在。如果是这样,它会将新的 Activity 对象更新到任务,以便任务可以更新新的进度条。我已经对此进行了测试,并且可以正常工作。这应该让您更好地了解如何使用 AsyncTaskLoader 和管理简历。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2020-08-08
    • 2018-09-10
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    相关资源
    最近更新 更多