2011-02-06 35 views
1

編輯:添加了一個額外的錯誤和我所做的代碼的修訂。alertdialog錯誤與事件

我是java/android新手。我試圖在我的DataRobot類中觸發事件時在我的SmartApp類中創建一個AlertDialog。這樣做時出現錯誤。事件正在觸發並在SmartApp中成功調用該函數,但是當它到達AlertDialog alert = new AlertDialog.Builder(this).create();時,會向logcat顯示以下錯誤。有誰知道我做錯了什麼或更好的方式來實現我想要的?

Logcat error: 
02-05 22:39:27.081: VERBOSE/SmartApp(281): data alert event caught 
02-05 22:39:27.081: VERBOSE/SmartApp(281): inside sendalert 
02-05 22:39:27.090: WARN/System.err(281): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
02-05 22:39:27.122: WARN/System.err(281):  at android.os.Handler.<init>(Handler.java:121) 
02-05 22:39:27.122: WARN/System.err(281):  at android.app.Dialog.<init>(Dialog.java:101) 
02-05 22:39:27.141: WARN/System.err(281):  at android.app.AlertDialog.<init>(AlertDialog.java:63) 
02-05 22:39:27.141: WARN/System.err(281):  at android.app.AlertDialog.<init>(AlertDialog.java:59) 
02-05 22:39:27.161: WARN/System.err(281):  at android.app.AlertDialog$Builder.create(AlertDialog.java:786) 
02-05 22:39:27.161: WARN/System.err(281):  at cpe495.smartapp.SmartApp.sendAlert(SmartApp.java:169) 
02-05 22:39:27.171: WARN/System.err(281):  at cpe495.smartapp.SmartApp$3.dataAlertReceived(SmartApp.java:59) 
02-05 22:39:27.201: WARN/System.err(281):  at cpe495.smartapp.DataRobot.fireDataAlertEvent(DataRobot.java:96) 
02-05 22:39:27.201: WARN/System.err(281):  at cpe495.smartapp.DataRobot.analyzeData(DataRobot.java:32) 
02-05 22:39:27.211: WARN/System.err(281):  at cpe495.smartapp.SmartApp$1.dataReceivedReceived(SmartApp.java:45) 
02-05 22:39:27.222: WARN/System.err(281):  at cpe495.smartapp.ConnectDevice.fireDataReceivedEvent(ConnectDevice.java:71) 
02-05 22:39:27.222: WARN/System.err(281):  at cpe495.smartapp.ConnectDevice.run(ConnectDevice.java:42) 
02-05 22:39:27.242: WARN/System.err(281):  at java.lang.Thread.run(Thread.java:1096) 

//my smartapp class main ui 
public class SmartApp extends Activity implements OnSharedPreferenceChangeListener { 
    TextView smartConnectionStatus; 
    TextView testOutputView; 
    Thread cThread; 
    private ConnectDevice cD = new ConnectDevice(); 
    private DataRobot dR = new DataRobot(); 
    private DataBuilder dB = new DataBuilder(); 
    private DataSender dS = new DataSender(); 


    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.intro); 



     cD.addDataReceivedListener(new DataReceivedListener() { 
      @Override 
      public void dataReceivedReceived(DataReceivedEvent event) { 
       // TODO Auto-generated method stub 
       dR.analyzeData(event.getData()); 
      } 
     }); 
     dR.addDataAlertListener(new DataAlertListener() { 
      @Override 
      public void dataAlertReceived(DataAlertEvent event) { 
       Log.v("SmartApp", "data alert event caught"); 
       sendAlert(); 
      } 
     }); 
    } 
    /* Function for sending alerts that the user has exceeded a stress index */ 
    public void sendAlert() { 
     Log.v("SmartApp", "inside sendalert"); 
     AlertDialog alert = new AlertDialog.Builder(this).create(); 
     Log.v("SmartApp", "after builder1"); 
     //Vibrator vibrator; 
     //vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
     //vibrator.vibrate(500); 
     alert.setMessage("Testing alert dialog..."); 
     alert.setCancelable(false); 
     alert.setButton("Ok", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       // TODO Auto-generated method stub 
       dialog.cancel(); 
      } 
     }); 
     Log.v("SmartApp", "after builder2"); 
     //AlertDialog alert = builder.create(); 
     alert.setTitle("Title"); 
     Log.v("SmartApp", "after builder3"); 
     alert.show(); 
     Log.v("SmartApp", "after builder4"); 
    } 

} 

// datarobot class 
public class DataRobot extends Activity { 
/* This class is for analyzing the data */ 
private List _listeners = new ArrayList(); 
private List<DataAlertListener> _listeners2 = new ArrayList<DataAlertListener>(); 
private SmartDataObject data; 
private int sI1; 
private int sI2; 
private float w1; 
private float w2; 
private float w3; 
private int hRB; 
private int hRVMin; 
private int hRVMax; 

public boolean analyzeData(SmartDataObject temp) { 
    /* Analyze the data 
    * Returns true if data was successfully analyzed 
    * Returns false if an error occurred 
    */ 
    data = temp; 
    if(data.getHeartRate()>290) { 
     fireDataAlertEvent(); 
    } 
    fireDataAnalyzedEvent(data); 
    return true; //for now this will always return true 
} 

public synchronized void addDataAnalyzedListener(DataAnalyzedListener listener) { 
    _listeners.add(listener); 
} 
public synchronized void removeDataAnalyzedListener(DataAnalyzedListener listener) { 
    _listeners.remove(listener); 
} 
private synchronized void fireDataAnalyzedEvent(SmartDataObject temp) { 
    DataAnalyzedEvent dRE = new DataAnalyzedEvent(this, temp); 
    Iterator listeners = _listeners.iterator(); 
    while(listeners.hasNext()) { 
     ((DataAnalyzedListener)listeners.next()).dataAnalyzedReceived(dRE); 
    } 
} 
public interface DataAnalyzedListener { 
    public void dataAnalyzedReceived(DataAnalyzedEvent event); 
} 



public synchronized void addDataAlertListener(DataAlertListener listener) { 
    _listeners2.add(listener); 
} 
public synchronized void removeDataAlertListener(DataAlertListener listener) { 
    _listeners2.remove(listener); 
} 
private synchronized void fireDataAlertEvent() { 
    DataAlertEvent dAE = new DataAlertEvent(this); 
    Iterator listeners = _listeners2.iterator(); 
    while(listeners.hasNext()) { 
     ((DataAlertListener)listeners.next()).dataAlertReceived(dAE); 
    } 
} 
public interface DataAlertListener { 
    public void dataAlertReceived(DataAlertEvent event); 
} 
} 

public class DataAlertEvent extends EventObject { 
    public DataAlertEvent(Object source) { 
     super(source); 
     // TODO Auto-generated constructor stub 
    } 
} 

下面是添加的代碼試圖修復

02-06 10:27:30.673: VERBOSE/SmartApp(276): data alert event caught 
02-06 10:27:31.013: WARN/System.err(276): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
02-06 10:27:31.042: WARN/System.err(276):  at android.os.Handler.<init>(Handler.java:121) 
02-06 10:27:31.052: WARN/System.err(276):  at android.view.ViewRoot.<init>(ViewRoot.java:231) 
02-06 10:27:31.052: WARN/System.err(276):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 
02-06 10:27:31.062: WARN/System.err(276):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 
02-06 10:27:31.082: WARN/System.err(276):  at android.view.Window$LocalWindowManager.addView(Window.java:424) 
02-06 10:27:31.082: WARN/System.err(276):  at android.app.Dialog.show(Dialog.java:241) 
02-06 10:27:31.102: WARN/System.err(276):  at cpe495.smartapp.SmartApp$4.dataAlertReceived(SmartApp.java:80) 
02-06 10:27:31.102: WARN/System.err(276):  at cpe495.smartapp.DataRobot.fireDataAlertEvent(DataRobot.java:96) 
02-06 10:27:31.122: WARN/System.err(276):  at cpe495.smartapp.DataRobot.analyzeData(DataRobot.java:32) 
02-06 10:27:31.122: WARN/System.err(276):  at cpe495.smartapp.SmartApp$2.dataReceivedReceived(SmartApp.java:66) 
02-06 10:27:31.133: WARN/System.err(276):  at cpe495.smartapp.ConnectDevice.fireDataReceivedEvent(ConnectDevice.java:71) 
02-06 10:27:31.133: WARN/System.err(276):  at cpe495.smartapp.ConnectDevice.run(ConnectDevice.java:42) 
02-06 10:27:31.153: WARN/System.err(276):  at java.lang.Thread.run(Thread.java:1096) 

public class SmartApp extends Activity implements OnSharedPreferenceChangeListener { 
    TextView smartConnectionStatus; 
    TextView testOutputView; 
    Thread cThread; 
    private ConnectDevice cD = new ConnectDevice(); 
    private DataRobot dR = new DataRobot(); 
    private DataBuilder dB = new DataBuilder(); 
    private DataSender dS = new DataSender(); 


    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.intro); 

    final AlertDialog alert = new AlertDialog.Builder(this).create(); 
    Log.v("SmartApp", "inside sendalert"); 
    //AlertDialog alert = new AlertDialog.Builder(this).create(); 
    Log.v("SmartApp", "after builder1"); 
    //Vibrator vibrator; 
    //vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
    //vibrator.vibrate(500); 
    alert.setMessage("Testing alert dialog..."); 
    alert.setCancelable(false); 
    alert.setButton("Ok", new DialogInterface.OnClickListener() { 
     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      // TODO Auto-generated method stub 
      dialog.cancel(); 
     } 
    }); 
    Log.v("SmartApp", "after builder2"); 
    //AlertDialog alert = builder.create(); 
    alert.setTitle("Title"); 

     cD.addDataReceivedListener(new DataReceivedListener() { 
      @Override 
      public void dataReceivedReceived(DataReceivedEvent event) { 
       // TODO Auto-generated method stub 
       dR.analyzeData(event.getData()); 
      } 
     }); 
     dR.addDataAlertListener(new DataAlertListener() { 
      @Override 
      public void dataAlertReceived(DataAlertEvent event) { 
       Log.v("SmartApp", "data alert event caught"); 
       sendAlert(); 
          alert.show(); 
      } 
     }); 
    } 

} 

回答

1

您必須創建和用戶界面線程顯示警告對話框或:

  1. 創建UI線程處理器。

    Handler mHandler = new Handler(); 
    
  2. 創建一個線程

    class A implements Runnable { 
        public void run() { 
         // create and show alert here 
        } 
    } 
    
  3. 當事件被激活,請致電:

    A a = new A(); 
    mHandler.post(a); 
    
+0

這工作。謝謝您的幫助。我昨天試了一下,但一定有什麼不對。正如我所需要的那樣工作。謝謝merrymenvn。 – prolink007 2011-02-07 19:58:29

0

AlertDialog.Builder(本).create();應該從UI線程中調用。嘗試將create()方法移動到UI線程。

+0

我把AlertDialog的創造SmartApp的onCreate方法內。然後我將alert.show()移到了我的dataAlertReceived函數中。我必須使AlertDialog alert = new AlertDialog.Builder(this).create()final才能工作。當該對話框應該被調用時,我得到附加到OP的logcat錯誤。有關更多詳細信息,請參閱OP。 – prolink007 2011-02-06 16:34:40

0

這是我得到了同樣的錯誤,所以,謝謝喲的建議,以把它放在UI線程上。我在Xamarin雖然工作,對我來說,解決方案實際上是把它像這樣在主線程:

 Xamarin.Forms.Device.BeginInvokeOnMainThread(() => 
     { 
      page.DisplayAlert("Alert", message, null, "Cancel"); 
     });