Android:无法显示AsyncTask类的对话框

时间:2015-04-01 02:04:03

标签: java android android-asynctask progressdialog

我为我的Android应用程序构建了更新类。它工作正常,除了下载内部AsyncTask类。

我想在下载文件时在LoadingActivity中显示进度对话框。

首先,我在 onCreate 方法中调用更新类。作为参数,我发送活动上下文。然后在更新类构造函数中,我调用检查内部类(AsyncTask),它从URL解析JSON响应(正常工作)并调用下载(下一步) 更新内部类),这就是问题。

当我尝试创建 ProgressDialog 对象时,编译器会抛出:

04-01 02:53:56.864  24393-24425/pl.com.mpkostrowiec.schedule E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:299)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
            at java.util.concurrent.FutureTask.run(FutureTask.java:239)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
            at java.lang.Thread.run(Thread.java:838)
     Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
            at android.os.Handler.<init>(Handler.java:197)
            at android.os.Handler.<init>(Handler.java:111)
            at android.app.Dialog.<init>(Dialog.java:107)
            at android.app.AlertDialog.<init>(AlertDialog.java:114)
            at android.app.AlertDialog.<init>(AlertDialog.java:98)
            at android.app.ProgressDialog.<init>(ProgressDialog.java:77)
            at pl.com.mpkostrowiec.schedule.DownloadAsync.<init>(DownloadAsync.java:30)
            at pl.com.mpkostrowiec.schedule.Updates$Check.doInBackground(Updates.java:128)
            at pl.com.mpkostrowiec.schedule.Updates$Check.doInBackground(Updates.java:74)
            at android.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask.run(FutureTask.java:234)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
            at java.lang.Thread.run(Thread.java:838)

我认为ProgressDialog构造函数无法从Updates类访问上下文变量,因此我尝试将其作为参数发送,但它无法解决问题。

LoadingActivity 类:

package pl.com.mpkostrowiec.schedule;

import ...

public class LoadingActivity extends Activity {

    private final Preferences preferences = new Preferences(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading);

        preferences.savePreference("Preferences", "firstRun", "1");

        // Check if first run
        if (preferences.readPreference("Preferences", "firstRun").equals("0")) {
            System.out.println("****************** Not first run");
        } else {

            // Create directory
            File dir = this.getDir("Versions", MODE_PRIVATE);

            new Updates(this);
        }
    }
}

更新类:

package pl.com.mpkostrowiec.schedule;

import ...

interface AfterExecuteListener {
    public void afterDownload(String[] versionData, int type);
}

public class Updates implements AfterExecuteListener{

    private static VersionsTable versionsTable;
    private Context context;

    public static Boolean status_current = false;
    public static Boolean status_new = false;

    private final int TYPE_CURRENT = 0;
    private final int TYPE_NEW = 1;
    private static final String URL = "http://www.mpkostrowiec.com.pl/preview/";
    private static final String GET_VERSIONS = "includes/android/versions.php";
    private static final String RESOURCES = "resources/android/versions/";
    private static final String EXTENSION = ".db";

    public Updates(Context context) {
        this.context = context;

        versionsTable = new VersionsTable(this.context);
        new Check(TYPE_CURRENT).execute();
    }

    public final void afterDownload(String[] versionData, int type) {

        // Add version data to DB
        versionsTable.open();
        versionsTable.add(versionData);
        versionsTable.close();

        // Set status
        if (type == TYPE_CURRENT) {
            System.out.println("****************** Downloaded: " + type);
            status_current = true;
        } else if (type == TYPE_NEW) {
            System.out.println("****************** Downloaded: " + type);
            status_new = true;
        }

        Schedule();
    }

    private void Schedule() {
        if (status_current) {
            if (status_new) {
                System.out.println("****************** SUCCESS");
            } else {
                new Check(TYPE_NEW).execute();
            }
        }
    }

    private class Check extends AsyncTask<String, Integer, String> {

        public AfterExecuteListener mListener;
        private int type;

        public Check(int type) {
            this.type = type;
        }

        @Override
        protected String doInBackground(String... Url) {

            String[] typeStr = {"current", "new"};

            // Get versions form URL
            JSONObject json = null;
            String versions = null;
            HttpResponse response;
            HttpClient myClient = new DefaultHttpClient();
            HttpPost myConnection = new HttpPost(URL + GET_VERSIONS);

            try {
                response = myClient.execute(myConnection);
                versions = EntityUtils.toString(response.getEntity(), "UTF-8");

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try{
                JSONObject jObject = new JSONObject(versions);
                json = jObject.getJSONObject(typeStr[type]);

                if (json.length() > 1) {
                    String[] versionData = {json.getString("id"),
                            json.getString("name"),
                            json.getString("expDate")};

                    versionsTable.open();
                    Boolean idExist = versionsTable.check(versionData[0]);
                    versionsTable.close();

                    // Check version
                    if (!idExist) {

                        // Start downloading
                        Download download = new Download(versionData, type);
                        download.setListener(Updates.this);
                        download.execute(URL + RESOURCES + versionData[0] + EXTENSION);
                    }
                } else {

                    // If array contains only false field then do not update
                    if (type == TYPE_CURRENT) {
                        Updates.status_current = true;
                    } else if (type == TYPE_NEW) {
                        Updates.status_new = true;
                    }

                    Schedule();
                }

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

            return null;
        }
    }

    private class Download extends AsyncTask<String, Integer, String> {

        public ProgressDialog mProgressDialog;
        public AfterExecuteListener mListener;

        private String[] versionData;
        private int type;

        public Download(String[] versionData, int type) {
            this.versionData = versionData;
            this.type = type;

            // Create progress dialog
            mProgressDialog = new ProgressDialog(context);

            // Set your progress dialog Title
            mProgressDialog.setTitle("Updating...");

            // Set your progress dialog Message
            mProgressDialog.setMessage("Update in progress. Please wait.");
            mProgressDialog.setIndeterminate(false);
            mProgressDialog.setMax(100);
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        }

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

            // Show progress dialog
            mProgressDialog.show();
        }

        @Override
        protected String doInBackground(String... Url) {
            try {
                java.net.URL url = new URL(Url[0]);
                URLConnection connection = url.openConnection();
                connection.connect();

                // Detect the file lenghth
                int fileLength = connection.getContentLength();

                // Locate storage location
                String filepath = context.getApplicationInfo().dataDir + "/Versions";

                // Download the file
                InputStream input = new BufferedInputStream(url.openStream());

                // Save the downloaded file
                OutputStream output = new FileOutputStream(filepath + "/" + versionData[0] + ".db");

                byte data[] = new byte[1024];
                long total = 0;
                int count;
                while ((count = input.read(data)) != -1) {
                    total += count;
                    // Publish the progress
                    publishProgress((int) (total * 100 / fileLength));
                    output.write(data, 0, count);
                }

                // Close connection
                output.flush();
                output.close();
                input.close();
            } catch (Exception e) {
                // Error Log
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);

            // Update the progress dialog
            mProgressDialog.setProgress(progress[0]);
        }

        @Override
        protected void onPostExecute(String result) {

            // Dismiss the progress dialog
            mProgressDialog.dismiss();

            mListener.afterDownload(versionData, type);
        }

        private void setListener(AfterExecuteListener listener) {
            mListener = listener;
        }
    }
}

0 个答案:

没有答案