【问题标题】:async task does not work properly异步任务无法正常工作
【发布时间】:2015-08-27 11:24:29
【问题描述】:

您好,我有一个从网站数据库获取用户的功能 我的功能

private void get_users() {

    try {
        url = "my address";

        dbGetData3 = new DbGetData();
        new Thread(new Runnable() {
            public void run() {
                data = dbGetData3.getDataFromDB(url);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        userha = parseJSON3(data);
                    }
                });
            }
        }).start();

        Toast.makeText(context, "please wait ", Toast.LENGTH_LONG)
                .show();
    } catch (Exception e) {
        toast(9);
    }

现在我想在获取数据完成时添加一个加载进度条。

我像这样使用 AsyncTask:

private class LongOperation extends AsyncTask<String, Void, String> {
    protected void onPreExecute() {

          progressDialog = new ProgressDialog(Login.this);
          progressDialog.setTitle("Processing...");
          progressDialog.setMessage("Please wait...");
          progressDialog.setCancelable(true); 
          progressDialog.show();

    }

    protected String doInBackground(String... params) {
        try {
            get_users();
        } catch (Exception e) {
        }
        return null;
    }

    protected void onPostExecute(String result) {
        progressDialog.dismiss();
    }
}

我使用此代码执行

        mytask = new LongOperation();
        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
            mytask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        else
            mytask.execute();
        imageView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                onCreate(savedInstanceState);
            }
        });

但我没有显示进度对话框(让用户工作)

我像这样更改我的代码:

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){
                mytask.onPreExecute();
                mytask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

            }
            else
            {
                mytask.onPreExecute();
                mytask.execute();
            }

然后我的进度对话框总是显示

我在 stackoverflow 中测试其他代码,例如

AsyncTask doInBackground does not run

AsyncTask called from Handler will not execute doInBackground

Android SDK AsyncTask doInBackground not running (subclass)

但这对我不起作用 请帮我坦克你

【问题讨论】:

  • 写 super.onPreExecute();在你的 onPreExecute()
  • 进度对话框始终显示
  • 如果它总是显示然后关闭它。简单。
  • 此外,我建议在完成此操作后转到 googl'e 自己的 volley 库进行网络调用并使用模型类来设置您的数据。这是一种模块化且更好的方法
  • 我把解雇,但那是行不通的

标签: android android-asynctask progressdialog


【解决方案1】:

Consdier 使用 LoaderManageran AsyncTaskLoader 处理这类事情。

AsyncTask 让人头疼,因为您必须通过屏幕旋转等来管理它们的生命周期。使用 LoaderManager,所有这些都已成为过去。

下面是一个加载“项目”列表的加载器示例。

public class ItemsLoader extends AsyncTaskLoader<List<Item>> {

private static final String TAG = "ItemsLoader";

private List<Item> mItems;
private ItemUpdatedReceiver mObserver;
private int mSomeParam;

public static class ItemUpdatedReceiver extends BroadcastReceiver {

    private static final String TAG = "ItemLoader";

    final ItemsLoader mLoader;

    public ItemUpdatedReceiver(ItemsLoader mLoader) {
        this.mLoader = mLoader;

        // listen for changes to the account we're using
        IntentFilter filter = new IntentFilter(GlobalConstants.ACTION_ITEMS_UPDATED);
        LocalBroadcastManager.getInstance(mLoader.getContext()).registerReceiver(this, filter);
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();
        if (GlobalConstants.ACTION_ITEMS_UPDATED.equals(action)) {

            mLoader.onContentChanged();
        }


    }
}

public void setSomeParam(int someParam){
    mSomeParam = someParam;
    onContentChanged();
}

public ItemsLoader(Context context, int someParam) {
    super(context);
    mSomeParam = someParam;
    onContentChanged();
}

@Override
public List<Item> loadInBackground() {

    // do whatever you need to do here

    ArrayList<Item> Items = new ArrayList<>();
    return Items;

}

/**
 * Called when there is new data to deliever to the client.
 *
 * @param data
 */
@Override
public void deliverResult(List<Item> data) {
    if (isReset()) {
        // an async query came in while the loader is stopped, we don't need the result
        //release resources if needed
        onReleaseResources(data);
    }

    List<Item> oldItems = mItems;
    mItems = data;

    if (isStarted()) {
        // If the Loader is currently started, we can immediately
        // deliver its results.
        super.deliverResult(mItems);
    }

    // At this point we can release the resources associated with
    // 'oldApps' if needed; now that the new result is delivered we
    // know that it is no longer in use.
    if (oldItems != null) {
        onReleaseResources(oldItems);
    }

}

@Override
protected void onStartLoading() {
    super.onStartLoading();
    if (mItems != null) {
        // If we currently have a result available, deliver it
        // immediately.
        deliverResult(mItems);
    }

    // start listening for changes
    if (mObserver == null) {
        mObserver = new ItemUpdatedReceiver(this);
    }

    if (takeContentChanged() || mItems == null) {
        // If the data has changed since the last time it was loaded
        // or is not currently available, start a load.
        forceLoad();
    }
}

/**
 * Handles a request to stop the Loader.
 */
@Override
protected void onStopLoading() {
    // Attempt to cancel the current load task if possible.
    cancelLoad();
}

/**
 * Handles a request to cancel a load.
 */
@Override
public void onCanceled(List<Item> items) {
    super.onCanceled(items);

    // At this point we can release the resources associated with 'profile'
    // if needed.
    onReleaseResources(items);
}

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

    // Ensure the laoder is stopped
    onStopLoading();

// At this point we can release the resources if needed.
    if (mItems != null) {
        onReleaseResources(mItems);
        mItems = null;
    }

    // Stop monitoring for changes.
    if (mObserver != null) {
        LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mObserver);
        mObserver = null;
    }
}

/**
 * Helper function to take care of releasing resources associated
 * with an actively loaded data set.
 */
private void onReleaseResources(List<Item> data) {
    // For a simple List<> there is nothing to do.  For something
    // like a Cursor, we would close it here.

}
}

要使用此类,您必须在您的活动中扩展 LoaderManager.LoaderCallbacks> 并覆盖方法:

 public Loader<List<Item>> onCreateLoader(int id, Bundle args) {
    // This is called when a new Loader needs to be created.  This
    // sample only has one Loader, so we don't care about the ID.
    // start the loading dialog here

    return new ItemsLoader(context);
}

public void onLoadFinished(Loader<List<Item>> loader, List<Item>data) {
    // do something with your data, hide the progress dialog
}

public void onLoaderReset(Loader<Cursor> loader) {
    // set the old data to null
}

真正开始加载:

getLoaderManager().initLoader(LOADER_ID, null, this);

【讨论】:

  • 我可以使用它从服务器获取数据并显示加载数据进度对话框吗?
  • 当你从一个活动或片段中使用它时,你有它开始和结束的回调,所以你可以在那里显示你的进度条。你可以在 loadInBackground() 方法中做任何你喜欢的事情,包括从服务器获取数据
  • 您的活动或片段将实现 LoaderManager.LoaderCallbacks> 当您准备好加载时,调用 getSupportLoaderManager().initLoader(LOADER_ID, null, this)
  • 这个类怎么用?
  • 我使用 get_user() 函数接收数据。我想在 get_user 工作完成时显示一个对话框。
猜你喜欢
  • 2019-03-22
  • 2020-12-21
  • 1970-01-01
  • 2014-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多