我开发了一个应用程序,它从互联网上获取内容,并在设备的屏幕上显示相应的内容。该程序工作得很好,有点慢。加载和显示内容大约需要3-4秒。我想把我的代码放在后台线程中完成所有工作(抓取Web内容并显示它)。另外,我想显示一个进度对话框。
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();
}*/
}
如果我使用此代码运行应用程序,我会得到:download failed。另一方面,如果我保留最后一个线程,应用程序崩溃,NullPointerException。我真的不知道该怎么做了。
如果你可以给我一个替代这个代码的话,我真的很感动,不只是一些提示,因为我是android的新手,我真的不太了解。感谢。
更新:
我不想显示下载进度,我想显示进度对话框,直到应用程序准备好显示完整内容。
答案 0 :(得分:2)
执行此操作的最佳方法是使用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方法。
答案 1 :(得分:1)
你应该像这样为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()中输入:
new YourTask().execute();
有关详细信息,请查看一次:
http://developer.android.com/reference/android/os/AsyncTask.html
答案 2 :(得分:0)
当您使用新线程时,您的应用程序崩溃,因为进度对话框未在那里初始化
在新线程中使用:
`progressDialog = ProgressDialog.show(Activity1.this, "","Loading...");
关于该警告对话框:基本上,params为null或逻辑抛出一些异常。它没有回归真实 所以检查ddms日志并在这里发布。
`