Android - получение исключения - PullRequest
1 голос
/ 09 сентября 2010

Я разрабатываю одно приложение, в котором я получаю исключение, и я знаю, что это глупая или маленькая ошибка, которую я делаю, но ваша помощь может поймать меня и сделать мой день:

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");
         }
    }   
}

В приведенном выше коде, если я сделаю i = 0 или i = 1 в функции tryDemo, значит, она работает успешно, но если я сделаю ее отличной от 0 или 1, тогда выдает исключение как «Demo - Demo Exception».

Я не уверен, но я думаю, что исключение возникает из getApplicationContext () .

Обновление: - 1

Исключение, которое я получаю, следующим образом:

alt text

Обновление: - 2 Если я удаляю "ветку""часть и написал весь код функции в событии нажатия кнопки и заменил" getApplicationContext () "на v.getContext (), тогда он работает успешно ......... но я хочу реализовать его в THREAD.

Пожалуйста, помогите мне и поймайте меня ...

спасибо

Ответы [ 4 ]

1 голос
/ 11 сентября 2010

Несколько вещей не так с этим.Во-первых, вы никогда, НИКОГДА не трогаете какие-либо элементы пользовательского интерфейса из созданного вами потока.

Вам понадобится подписаться с обработчиками потоков: http://developer.android.com/reference/android/os/Handler.html

То, как они работают,Вы инициализируете их в своем обычном потоке пользовательского интерфейса.(поток, вызываемый вашим методом 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.html и http://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);
    }
}

Это, если вы хотите получить немного фантазии, вы полностью разделяете код пользовательского интерфейса и код рабочего потока.Если ваша фоновая задача не займет много времени, вы можете использовать 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

1 голос
/ 09 сентября 2010

Просто прочитайте свои журналы: D Вы не вызывали Looper.prepare ()

Если я прав, вы должны обернуть свой код AlertDialog с помощью Looper.prepare () и Looper.loop ()

Так это выглядит так:

Looper.prepare()
// AlertDialog code
Looper.loop()
1 голос
/ 09 сентября 2010

Комментарии к оформлению заказа в этом сообщении:

Использование повсеместного использования контекста приложения?

Также, если вы замените getApplicationContext () на actiivtyname.getApplicationContext (), какие ошибки вы получаете

1 голос
/ 09 сентября 2010

Вы, вероятно, получаете RuntimeException.Я попытался вызвать создание некоторого диалога в потоке, не являющемся потоком пользовательского интерфейса, и получил следующее:

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() {
            ...
        }
    });
}
...