1

我正在开发一个应用程序,其中我遇到了异常,我知道这是我正在做的愚蠢或小错误,但你的帮助可能会让我失望并让我开心:

public class Demo extends Activity
{
    Button btnDemo;
        Thread t;
    AlertDialog alertDialog;

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

              btnDemo = (Button) findViewById(R.id.btnDemo);
          btnDemo.setOnClickListener(new OnClickListener() {
                      public void onClick(final View v) {

                          t=new Thread() {
                               public void run() {
                                    tryDemo();
                               }
                         };
                         t.start(); 
                      }
                });
     }

    public void tryDemo()
    {

          try
         {
              int i = 5;

              if(i == 0 || i == 1)
              {
                    Intent intent_success = new Intent(getApplicationContext(), Main_Activity.class);
                    startActivity(intent_success);
              }
              else
              {
                alertDialog = new  AlertDialog.Builder(getApplicationContext()).create();
                alertDialog.setTitle("Demo");
                alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int which) {
                       //here you can add functions
                } }); 
                alertDialog.setIcon(R.drawable.icon);
                alertDialog.setMessage("Sorry!! Either Username or Password Invalid");
                alertDialog.show();

              }
         }
         catch(Exception e)
         {
               Log.i("Demo", "Demo - Demo Exception");
         }
    }   
}

在上面的代码中,如果我在 tryDemo 函数中设置 i=0 或 i=1,则它运行成功,但如果我将其设置为 0 或 1 以外的值,则它会引发异常,如“Demo - Demo Exception”

我不确定,但我认为异常来自getApplicationContext()

更新:- 1

我得到的异常如下:

替代文字

更新:- 2 如果我删除“线程”部分并在按钮单击事件中编写整个函数代码,并用 v.getContext() 替换“getApplicationContext()”,那么它运行成功............ .但我想在线程中实现它。

请帮助我并抓住我...

谢谢

4

4 回答 4

1

你可能会得到一个RuntimeException. 我尝试在不是 UI 线程的线程中调用一些对话框创建并得到了这个:

09-09 00:46:37.702: ERROR/AndroidRuntime(763): Uncaught handler: thread Thread-10 exiting due to uncaught exception
09-09 00:46:37.724: ERROR/AndroidRuntime(763): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.os.Handler.<init>(Handler.java:121)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.view.ViewRoot.<init>(ViewRoot.java:192)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.view.Window$LocalWindowManager.addView(Window.java:392)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at android.app.Dialog.show(Dialog.java:231)
09-09 00:46:37.724: ERROR/AndroidRuntime(763):     at com.pkg.name.ToplistActivity$3.run(ToplistActivity.java:149)

解决方案是将您的 else 语句包装起来,例如:

else {
    runOnUiThread(new Runnable() {
        public void run() {
            ...
        }
    });
}
于 2010-09-09T08:00:00.793 回答
1

只需阅读您的日志:D 您还没有调用 Looper.prepare()

如果我是正确的,你应该用 Looper.prepare() 和 Looper.loop() 包装你的 AlertDialog 代码

所以它看起来像:

Looper.prepare()
// AlertDialog code
Looper.loop()
于 2010-09-09T09:11:25.193 回答
1

结帐此帖子中的评论:

到处使用应用程序上下文?

另外,如果您将 getApplicationContext() 替换为 activename.getApplicationContext() 您会遇到什么错误?

于 2010-09-09T14:13:55.873 回答
1

这有几件事不对劲。首先,您永远不会触摸您创建的任何线程中的任何 UI 元素。

您需要熟悉线程处理程序:http: //developer.android.com/reference/android/os/Handler.html

它们的工作方式是,您在正常的 UI 线程中初始化它们。(调用您的 onCreate() 方法的线程。)处理程序是您扩展以在线程之间进行通信的线程安全对象。

所以,在你的 onCreate() 上:

Handler pHandler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            Bundle bundle = msg.getData();
            int msg_type = bundle.getInt("TYPE");
            if (msg_type == MyThread.ERROR_MSG)
            {
                 ///SOMETHING HAPPENED
                 return;
            }
            else
            {
                //background task finished ok
            }
        }
    };

然后,从您的 run() 方法中,您使用 Bundle 和 Message 对象向它发送一条消息。 http://developer.android.com/reference/android/os/Bundle.htmlhttp://developer.android.com/reference/android/os/Message.html

我喜欢这样做的方式,保持清洁是扩展 Thread 类以增加一点一致性......

class MyThead extends Thread
{
    public final int ERROR_MSG = 0;
    public final int OK_MSG = 1;
    Handler mHandler;

    MyThread(Handler pHandler)
    {
        mHandler = pHandler;
    }

    @Override
    public void run()
    {
        //send a message back to the ui thread....
        Message msg = new Message();
        Bundle bundle = new Bundle();
        bundle.putInt("TYPE", OK_MSG);
        msg.setData(bundle);
        mHandler.sendMessage(msg);
    }
}

如果你想要花哨一点,你可以将 UI 代码和工作线程代码完全分开。如果您的后台任务不会花费很长时间,您可以使用前面描述的 runonUiThread()。

您可能还想使用 AsyncTask,请参阅:http: //developer.android.com/reference/android/os/AsyncTask.html

这是他们页面中的一个示例,其用法相当简单:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

但最终,如果用户在您的任务运行时改变方向,这些方法并不完美。(或者如果您的活动因任何其他原因被终止。)在这种情况下,您需要设置一个服务:http: //developer.android.com/reference/android/app/Service.html

于 2010-09-10T23:56:04.763 回答