Android异步任务下载失败错误

发布于 2024-12-09 03:42:31 字数 3740 浏览 1 评论 0原文

我开发了一个应用程序,它从互联网获取内容并相应地在设备的屏幕上显示它。该程序运行得很好,就是有点慢。加载并显示内容大约需要 3-4 秒。我想将完成所有工作(抓取网页内容并显示它)的代码放在后台线程中。另外,我想显示一个进度对话框。

public class Activity1 extends Activity
{
    private ProgressDialog progressDialog;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new AsyncTask<Integer, Integer, Boolean>()
        {
            ProgressDialog progressDialog;

            @Override
            protected void onPreExecute()
            {
                /*
                 * This is executed on UI thread before doInBackground(). It is
                 * the perfect place to show the progress dialog.
                 */
                progressDialog = ProgressDialog.show(Activity1.this, "",
                        "Loading...");
            }

            @Override
            protected Boolean doInBackground(Integer... params)
            {
                if (params == null)
                {
                    return false;
                }
                try
                {
                    /*
                     * This is run on a background thread, so we can sleep here
                     * or do whatever we want without blocking UI thread. A more
                     * advanced use would download chunks of fixed size and call
                     * publishProgress();
                     */
                    Thread.sleep(params[0]);
                    // HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME
                }
                catch (Exception e)
                {
                    Log.e("tag", e.getMessage());
                    /*
                     * The task failed
                     */
                    return false;
                }

                /*
                 * The task succeeded
                 */
                return true;
            }

            @Override
            protected void onPostExecute(Boolean result)
            {
                progressDialog.dismiss();
                /*
                 * Update here your view objects with content from download. It
                 * is save to dismiss dialogs, update views, etc., since we are
                 * working on UI thread.
                 */
                AlertDialog.Builder b = new AlertDialog.Builder(Activity1.this);
                b.setTitle(android.R.string.dialog_alert_title);
                if (result)
                {
                    b.setMessage("Download succeeded");
                }
                else
                {
                    b.setMessage("Download failed");
                }
                b.setPositiveButton(getString(android.R.string.ok),
                        new DialogInterface.OnClickListener()
                        {

                            @Override
                            public void onClick(DialogInterface dlg, int arg1)
                            {
                                dlg.dismiss();
                            }
                        });
                b.create().show();
            }
        }.execute(2000);

      /*  new Thread()
        {
            @Override
            public void run()
            {

                // dismiss the progressdialog
                progressDialog.dismiss();
            }
        }.start();
    }*/
}

如果我使用此代码运行应用程序,我会得到: 下载失败 。另一方面,如果我保留最终线程,应用程序将崩溃,NullPointerException。我真的不知道该怎么办了。

如果您能为我提供此代码的替代方案,而不仅仅是一些提示,我将非常感激,因为我是 Android 新手,而且我真的了解不多。谢谢。

更新:

我不想显示下载进度,我想显示进度对话框,直到应用程序准备好显示完整内容。

I've developed an application that takes content from the internet and shows it accordingly on the device's screen . The program works just fine , a little bit slow . It takes about 3-4 seconds to load and display the content . I would like to put my code that does all the work ( grabbing web content and displaying it) in a background thread . Also , I'd like to show a progress dialog .

public class Activity1 extends Activity
{
    private ProgressDialog progressDialog;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new AsyncTask<Integer, Integer, Boolean>()
        {
            ProgressDialog progressDialog;

            @Override
            protected void onPreExecute()
            {
                /*
                 * This is executed on UI thread before doInBackground(). It is
                 * the perfect place to show the progress dialog.
                 */
                progressDialog = ProgressDialog.show(Activity1.this, "",
                        "Loading...");
            }

            @Override
            protected Boolean doInBackground(Integer... params)
            {
                if (params == null)
                {
                    return false;
                }
                try
                {
                    /*
                     * This is run on a background thread, so we can sleep here
                     * or do whatever we want without blocking UI thread. A more
                     * advanced use would download chunks of fixed size and call
                     * publishProgress();
                     */
                    Thread.sleep(params[0]);
                    // HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME
                }
                catch (Exception e)
                {
                    Log.e("tag", e.getMessage());
                    /*
                     * The task failed
                     */
                    return false;
                }

                /*
                 * The task succeeded
                 */
                return true;
            }

            @Override
            protected void onPostExecute(Boolean result)
            {
                progressDialog.dismiss();
                /*
                 * Update here your view objects with content from download. It
                 * is save to dismiss dialogs, update views, etc., since we are
                 * working on UI thread.
                 */
                AlertDialog.Builder b = new AlertDialog.Builder(Activity1.this);
                b.setTitle(android.R.string.dialog_alert_title);
                if (result)
                {
                    b.setMessage("Download succeeded");
                }
                else
                {
                    b.setMessage("Download failed");
                }
                b.setPositiveButton(getString(android.R.string.ok),
                        new DialogInterface.OnClickListener()
                        {

                            @Override
                            public void onClick(DialogInterface dlg, int arg1)
                            {
                                dlg.dismiss();
                            }
                        });
                b.create().show();
            }
        }.execute(2000);

      /*  new Thread()
        {
            @Override
            public void run()
            {

                // dismiss the progressdialog
                progressDialog.dismiss();
            }
        }.start();
    }*/
}

If I run the application with this code , I get this : download failed . On the other hand , if I keep the final thread , the app crashes , NullPointerException . I really don't know what to do anymore .

I would really appreaciate if you could give me an alternative to this code , not just some hints because I'm new to android and I really don't know much . Thanks.

UPDATE :

I don't want to display the progress of the download , I want to display the progress dialog until the app is ready to display the full content.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千里故人稀 2024-12-16 03:42:31

执行此操作的最佳方法是使用 AsyncTask 类,因为它允许您执行一些后台进程并同时更新 UI(在您的情况下,它是一个进度条)。

这是示例代码:

ProgressDialog mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
DownloadFile downloadFile = new DownloadFile();
downloadFile.execute("the url to the file you want to download");

AsyncTask 将如下所示:

private class DownloadFile extends AsyncTask<String, Integer, String>{
    @Override
    protected String doInBackground(String... url) {
        int count;
        try {
            URL url = new URL(url[0]);
            URLConnection conexion = url.openConnection();
            conexion.connect();
            // this will be useful so that you can show a tipical 0-100% progress bar
            int lenghtOfFile = conexion.getContentLength();

            // downlod the file
            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream("/sdcard/somewhere/nameofthefile.ext");

            byte data[] = new byte[1024];

            long total = 0;

            while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                publishProgress((int)(total*100/lenghtOfFile));
                output.write(data, 0, count);
            }

            output.flush();
            output.close();
            input.close();
        } catch (Exception e) {}
        return null;
    }

上面的方法 (doInBackground) 始终在后台线程上运行。您不应该在那里执行任何 UI 任务。另一方面,onProgressUpdate 在 UI 线程上运行,因此您将更改进度条:

@Override
public void onProgressUpdate(String... args){
    // here you will have to update the progressbar
    // with something like
    mProgressDialog.setProgress(args[0]);
}

}
如果您想在文件完全下载后执行某些代码,您还需要重写 onPostExecute 方法。

The best approach to do this is by using the AsyncTask class, as it will allow you to execute some background process and update the UI at the same time (in your case, it's a progress bar).

This is an example code:

ProgressDialog mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
DownloadFile downloadFile = new DownloadFile();
downloadFile.execute("the url to the file you want to download");

The AsyncTask will look like this:

private class DownloadFile extends AsyncTask<String, Integer, String>{
    @Override
    protected String doInBackground(String... url) {
        int count;
        try {
            URL url = new URL(url[0]);
            URLConnection conexion = url.openConnection();
            conexion.connect();
            // this will be useful so that you can show a tipical 0-100% progress bar
            int lenghtOfFile = conexion.getContentLength();

            // downlod the file
            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream("/sdcard/somewhere/nameofthefile.ext");

            byte data[] = new byte[1024];

            long total = 0;

            while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                publishProgress((int)(total*100/lenghtOfFile));
                output.write(data, 0, count);
            }

            output.flush();
            output.close();
            input.close();
        } catch (Exception e) {}
        return null;
    }

The method above (doInBackground) runs always on a background thread. You shouldn't do any UI tasks there. On the other hand, the onProgressUpdate runs on the UI thread, so there you will change the progress bar:

@Override
public void onProgressUpdate(String... args){
    // here you will have to update the progressbar
    // with something like
    mProgressDialog.setProgress(args[0]);
}

}
You will also want to override the onPostExecute method if you want to execute some code once the file has been downloaded completely.

无可置疑 2024-12-16 03:42:31

您应该为 AsyncTask 创建一个内部类,如下所示:

private class YourTask extends AsyncTask<Context, Void, Void>
{

ProgressDialog dialog = new ProgressDialog(mContext);

    protected void onPreExecute()
    {
       dialog.setMessage("loading..");
       dialog.show();
    }

    protected Void doInBackground(Context... params)
    {

                   // ...


        return null;
    }

    protected void onPostExecute(final Void unused)
    {
        dialog.dismiss();
    }
}

并在 onCreate() put 中:

     new YourTask().execute();

要了解更多详细信息,您应该检查一次:

http://developer.android.com/reference/android/os/AsyncTask.html

You should create an inner class for AsyncTask like this :

private class YourTask extends AsyncTask<Context, Void, Void>
{

ProgressDialog dialog = new ProgressDialog(mContext);

    protected void onPreExecute()
    {
       dialog.setMessage("loading..");
       dialog.show();
    }

    protected Void doInBackground(Context... params)
    {

                   // ...


        return null;
    }

    protected void onPostExecute(final Void unused)
    {
        dialog.dismiss();
    }
}

and in onCreate() put :

     new YourTask().execute();

and for more detail you should check this once:

http://developer.android.com/reference/android/os/AsyncTask.html

陌路黄昏 2024-12-16 03:42:31

当您使用新线程时,您的应用程序崩溃,因为进度对话框未

在新线程使用内部初始化:

`progressDialog = ProgressDialog.show(Activity1.this, "","Loading...");

以及关于该警报对话框:基本上要么参数为空,要么逻辑抛出一些异常。它没有返回 true
因此,请检查 ddms 日志并将其发布到此处。

`

When you use the new thread, your app crashes because the progress dialog is not initialized there

Inside your new thread use:

`progressDialog = ProgressDialog.show(Activity1.this, "","Loading...");

and about that alert dialog: Basically either params is null or the logic is throwing some exception. It's not returning true
so check the ddms logs and post them here.

`

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文