如果在获取JSON数据时没有互联网连接或URL格式错误,则强制关闭

时间:2011-02-22 18:04:14

标签: android json exception-handling

哎, 我是Android的新手,我有一点问题。我正在运行asynctask来在后台从Web获取json数据。这很好用,但是当没有互联网连接或json解析错误或URL格式错误时,应用程序强制关闭。有没有办法显示自定义错误而不是强制关闭应用程序?当然让应用程序保持打开状态。这是我简单的代码:

public class Main extends Activity {
    public static final int ACTIVITY_CREATE = 0;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new LongOperation(Main.this).execute();
    }


    class LongOperation extends AsyncTask<String, Void, String> {
        private Main longOperationContext = null;
        private static final int ACTIVITY_CREATE = 0;

        public LongOperation(Main context) {
            longOperationContext = context;
        }

        @Override
        protected String doInBackground(String... params) {
            try {

          //JSON Fetching and parsing here

            } catch (MalformedURLException e) {
                AlertDialog.Builder alertbox = new AlertDialog.Builder(Main.this);
                alertbox.setTitle("Error");
                alertbox.setMessage("URL Exception");
                alertbox.setNegativeButton("OK", null);
                alertbox.show();
            } catch (IOException e) {
                AlertDialog.Builder alertbox = new AlertDialog.Builder(Main.this);
                alertbox.setTitle("Error");
                alertbox.setMessage("IO Exception");
                alertbox.setNegativeButton("OK", null);
                alertbox.show();
            } catch (JSONException e) {
                AlertDialog.Builder alertbox = new AlertDialog.Builder(Main.this);
                alertbox.setTitle("Error");
                alertbox.setMessage("JSON Exception");
                alertbox.setNegativeButton("OK", null);
                alertbox.show();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
        //...
        }

        protected void onPreExecute() {
      //...
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        //...
        }
    }
}

提前致谢

编辑: 这是logcat:

02-22 19:33:47.881: WARN/dalvikvm(683): threadid=11: thread exiting with uncaught exception (group=0x40015560)
02-22 19:33:47.881: ERROR/AndroidRuntime(683): FATAL EXCEPTION: AsyncTask #3
02-22 19:33:47.881: ERROR/AndroidRuntime(683): java.lang.RuntimeException: An error occured while executing doInBackground()
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at java.lang.Thread.run(Thread.java:1019)
02-22 19:33:47.881: ERROR/AndroidRuntime(683): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at android.os.Handler.<init>(Handler.java:121)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at android.app.Dialog.<init>(Dialog.java:101)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at android.app.AlertDialog.<init>(AlertDialog.java:63)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at android.app.AlertDialog.<init>(AlertDialog.java:59)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at android.app.AlertDialog$Builder.create(AlertDialog.java:786)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at android.app.AlertDialog$Builder.show(AlertDialog.java:801)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at en.android.albumdownloader.Main$LongOperation.doInBackground(Main.java:130)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at en.android.albumdownloader.Main$LongOperation.doInBackground(Main.java:1)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
02-22 19:33:47.881: ERROR/AndroidRuntime(683):     ... 4 more
02-22 19:33:47.881: WARN/ActivityManager(71):   Force finishing activity en.android.albumdownloader/.Main
02-22 19:33:51.822: ERROR/WindowManager(683): Activity en.android.albumdownloader.Main has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@4057bdf0 that was originally added here
02-22 19:33:51.822: ERROR/WindowManager(683): android.view.WindowLeaked: Activity en.android.albumdownloader.Main has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@4057bdf0 that was originally added here
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.view.ViewRoot.<init>(ViewRoot.java:258)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.app.Dialog.show(Dialog.java:241)
02-22 19:33:51.822: ERROR/WindowManager(683):     at en.android.albumdownloader.Main$LongOperation.onPreExecute(Main.java:174)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.os.AsyncTask.execute(AsyncTask.java:391)
02-22 19:33:51.822: ERROR/WindowManager(683):     at en.android.albumdownloader.Main$1.onClick(Main.java:56)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.view.View.performClick(View.java:2485)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.view.View$PerformClick.run(View.java:9080)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.os.Handler.handleCallback(Handler.java:587)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.os.Handler.dispatchMessage(Handler.java:92)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.os.Looper.loop(Looper.java:123)
02-22 19:33:51.822: ERROR/WindowManager(683):     at android.app.ActivityThread.main(ActivityThread.java:3683)
02-22 19:33:51.822: ERROR/WindowManager(683):     at java.lang.reflect.Method.invokeNative(Native Method)
02-22 19:33:51.822: ERROR/WindowManager(683):     at java.lang.reflect.Method.invoke(Method.java:507)
02-22 19:33:51.822: ERROR/WindowManager(683):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-22 19:33:51.822: ERROR/WindowManager(683):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-22 19:33:51.822: ERROR/WindowManager(683):     at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)

您无法从后台线程显示对话框;您必须从UI线程执行此操作,否则您将在catch子句中导致另一个异常(我想你的logcat说“show()只能从UI线程调用”) 。您必须捕获异常并在AsyncTask中存储某种成员变量,然后在onPostExecute中显示错误对话框(或在onProgressUpdate中触发它)。