【问题标题】:Android viewpager AsyncTask finish when page changedAndroid viewpager AsyncTask 在页面更改时完成
【发布时间】:2014-07-23 07:20:59
【问题描述】:

我有查看寻呼机。我的浏览器包含 3 个片段。在第一个片段中,我有一个 AsyncTask 类。我用 AsyncTask 解析了 JSON,我可以在列表视图中显示它。 (一切正常)

当我转到下一个片段时,我在第一个片段中遇到的一个问题 AsyncTask 没有完成。当我在第二个片段中时,我的 AsyncTask 也在运行。当 viewpager 的页面发生变化时,如何编写代码来取消我的 AsyncTask?

这是我的来源(这是第一个片段来源;另一个片段来源相同,但唯一不同的是服务器网址):

public class StradaChefs1 extends Fragment {

public static CustomerStatistic stat;

private ConnectionDetector con;
private AlertDialogManager alert = new AlertDialogManager();

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

    View rootView = inflater.inflate(R.layout.strada_chefs_1, container,
            false);
    stat = new CustomerStatistic();

    con = new ConnectionDetector(getActivity());

    if (!con.isConnectingToInternet()) {
        alert.showAlertDialog(getActivity(),
                "You have not internet connection");
    } else {

        stat.execute("my urlllllllll"); // geo

    }

    return rootView;
}

public class CustomerStatistic extends AsyncTask<String, Void, String> {
    ProgressDialog pDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        pDialog = ProgressDialog.show(getActivity(), "Please Wait... ",
                "Loading... ");
        pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);

        pDialog.setCancelable(false);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... params) {
        return Utils.getJSONString(params[0]);
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        try {

            JSONArray mainJson = new JSONArray(result);

            String first = mainJson.getString(0);

            JSONObject jobject = new JSONObject(first);
            String image = jobject.getString("image");
            String String_title = jobject.getString("title");
            String String_name = jobject.getString("name");
            String String_desc = jobject.getString("description");

            String second = mainJson.getString(1);

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

        if (pDialog != null) {
            pDialog.dismiss();

            pDialog = null;
        }

    }

}

@Override
public void onResume() {
    Log.e("DEBUG", "onResume of HomeFragment");

    super.onResume();
}

@Override
public void onStop() {
    super.onStop();
    if (stat != null && stat.equals(AsyncTask.Status.RUNNING)) {
        stat.cancel(true);
        Toast.makeText(getActivity(), "finished", Toast.LENGTH_SHORT)
                .show();
    }

}
}

这是一个viewpager java代码

public class TabbedActivity1 extends Fragment {

private StradaChefs1 mfragment1;
private StradaChefs2 mfragment2;
private StradaChefs3 mfragment3;

private StradaChefs4 mfragment4;

SectionsPagerAdapter mSe;

public static final String TAG = TabbedActivity1.class.getSimpleName();


ViewPager mViewPager;
private ArrayList<Fragment> fragmentList;

public static TabbedActivity1 newInstance() {
    return new TabbedActivity1();
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.activity_item_one_1, container, false);

    mSe=new SectionsPagerAdapter(getChildFragmentManager());

    mViewPager = (ViewPager) v.findViewById(R.id.pager1);
    CirclePageIndicator circle=(CirclePageIndicator)v.findViewById(R.id.circleindicator1);
    mViewPager.setAdapter(mSe);
    circle.setViewPager(mViewPager);
    mfragment1 = new StradaChefs1();
    mfragment2 = new StradaChefs2();
    mfragment3 = new StradaChefs3();
    mfragment4 = new StradaChefs4();

    fragmentList = new ArrayList<Fragment>();
    fragmentList.add(mfragment1);
    fragmentList.add(mfragment2);
    fragmentList.add(mfragment3);
    fragmentList.add(mfragment4);

    mViewPager.setPageTransformer(false, new PageTransformer() {

        @Override
        public void transformPage(View page, float position) {
            page.setRotationY(position * -40);

        }
    });



    return v;
}


public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return 4;
    }

    @Override
    public CharSequence getPageTitle(int position) {

        return null;
    }
}

}

我该如何解决这个问题?

【问题讨论】:

    标签: android android-asynctask android-viewpager android-listfragment


    【解决方案1】:

    FragmentPagerAdapter 将除了显示的片段之外的其他片段保持在恢复状态,因此您不能使用onPauseonResume 来启动/停止AsyncTask。解决方案是实现一个自定义的OnPageChangeListener 并创建一个新的方法来显示片段。

    1) 创建LifecycleManager接口 该接口将有两个方法,每个ViewPager的Fragment都会实现它。这些方法如下:

    public interface FragmentLifecycle {
    
        public void onPauseFragment();
        public void onResumeFragment();
    
    }
    

    2)让每个Fragment实现接口
    3) 在每个片段中实现接口方法 - 在onPauseFragment 中停止AsyncTask,在onResumeFragment 中启动它
    4) ViewPager换页时调用接口方法可以在ViewPager上设置OnPageChangeListener,每次ViewPager显示另一页时获取回调

    5) 实现OnPageChangeListener 以调用您的自定义生命周期方法

    监听器知道新的位置,可以在PagerAdapter的帮助下调用新Fragment上的接口方法。我可以在这里调用onResumeFragment() 获取新片段,并调用onPauseFragment() 获取当前片段。

    我还需要存储当前片段的位置(最初当前位置等于 0),因为我不知道用户是从左到右还是从右到左滚动。看看我在代码中的意思:

    private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
    
        int currentPosition = 0;
    
        @Override
        public void onPageSelected(int newPosition) {
    
            FragmentLifecycle fragmentToShow = (FragmentLifecycle)pageAdapter.getItem(newPosition);
            fragmentToShow.onResumeFragment();
    
            FragmentLifecycle fragmentToHide = (FragmentLifecycle)pageAdapter.getItem(currentPosition);
            fragmentToHide.onPauseFragment();
    
            currentPosition = newPosition;
        }
    
        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) { }
    
        public void onPageScrollStateChanged(int arg0) { }
    };
    

    代码不是我写的。完整教程here

    【讨论】:

      【解决方案2】:

      当你启动异步任务时,设置标志 isRunning=true 当你试图从一个片段跳到另一个片段时,这意味着 根据片段生命周期,您正在暂停和停止当前片段

      所以在片段的 onStop 方法中,您可以检查 asynctask 的 isRunning 标志是否为真,如果是 取消异步任务

      这是我的逻辑希望它能帮助您实现您的要求

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-02
        • 1970-01-01
        • 1970-01-01
        • 2016-07-26
        • 1970-01-01
        相关资源
        最近更新 更多