每当应用程序最小化并恢复时,AsyncTaskLoader都会再次初始化

时间:2017-10-10 06:22:21

标签: android android-fragmentactivity viewpagerindicator asynctaskloader

当应用程序启动它工作正常我可以左右滑动没有任何问题。但是一旦app被最小化并且恢复它再次调用加载器并且数据被再次获取它导致更多的底部没有点。 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上的加载程序它工作正常,但无法处理方向更改任何更好的方法赞赏。

1 个答案:

答案 0 :(得分:0)

在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>

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