2012-03-20 191 views
0

我想讓我的第一個Android服務工作。我有這項服務,基本上產生隨機數。我希望它使用此服務更新Android視圖上的文本。我正在調度一個AsyncTask,它成功地更新了文本,但由於某種原因,我在Log中得到這個異常。這裏的例外:Android:AsyncTask拋出錯誤

03-20 09:58:37.242: ERROR/AndroidRuntime(594): FATAL EXCEPTION: AsyncTask #1 
     java.lang.RuntimeException: An error occured while executing doInBackground() 
     at android.os.AsyncTask$3.done(AsyncTask.java:200) 
     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
     at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 
     at java.lang.Thread.run(Thread.java:1096) 
     Caused by: java.lang.NullPointerException 
     at com.denniss.Main$2.doInBackground(Main.java:51) 
     at com.denniss.Main$2.doInBackground(Main.java:47) 
     at android.os.AsyncTask$2.call(AsyncTask.java:185) 
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
     ... 4 more 
03-20 09:58:37.272: WARN/ActivityManager(58): Force finishing activity com.denniss/.Main 
03-20 09:58:39.051: ERROR/ActivityThread(594): Activity com.denniss.Main has leaked ServiceConnection [email protected] that was originally bound here 
     android.app.ServiceConnectionLeaked: Activity com.denniss.Main has leaked ServiceConnection [email protected] that was originally bound here 
     at android.app.ActivityThread$PackageInfo$ServiceDispatcher.<init>(ActivityThread.java:1121) 
     at android.app.ActivityThread$PackageInfo.getServiceDispatcher(ActivityThread.java:1016) 
     at android.app.ContextImpl.bindService(ContextImpl.java:863) 
     at android.content.ContextWrapper.bindService(ContextWrapper.java:347) 
     at com.denniss.Main.onStart(Main.java:73) 
     at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129) 
     at android.app.Activity.performStart(Activity.java:3781) 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2636) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
     at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
     at android.os.Handler.dispatchMessage(Handler.java:99) 
     at android.os.Looper.loop(Looper.java:123) 
     at android.app.ActivityThread.main(ActivityThread.java:4627) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:521) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
     at dalvik.system.NativeStart.main(Native Method) 

Main.java

public class Main extends Activity { 

    private IRandomNumberService randomNumberService; 
    private int currentNumber = -1; 
    private boolean connected = false; 
    private TextView randomNumberText; 
    private ServiceConnection serviceConnection; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     System.out.println("******** onCreate"); 
     setContentView(R.layout.main); 
     randomNumberText = (TextView) findViewById(R.id.random_number); 

     serviceConnection = new ServiceConnection() { 
      public void onServiceConnected(ComponentName componentName, IBinder service) { 
       System.out.println("onService Connected Called"); 
       currentNumber = 1; 
       randomNumberService = IRandomNumberService.Stub.asInterface(service); 
      } 

      public void onServiceDisconnected(ComponentName componentName) { 
       System.out.println("Service Disconnected"); 
       randomNumberService = null; 
      } 
     }; 

     new AsyncTask<Void, Void, Void>() { 
      @Override 
      protected Void doInBackground(Void... voids) { 
       try { 
        currentNumber = randomNumberService.getRandomNumber(); 
        System.out.println("Current Number: " + currentNumber); 
       } catch (RemoteException e) { 
        e.printStackTrace(); 
       } 
       return null; 
      } 

      @Override 
      protected void onPostExecute(Void aVoid) { 
       super.onPostExecute(aVoid); 
       System.out.println("Setting Current Number: " + currentNumber); 
       randomNumberText.setText(new Integer(currentNumber).toString()); 
      } 
     }.execute(); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     System.out.println("******** on Start"); 
     if (!connected) { 
      connected = bindService(new Intent(Main.this, RandomNumberService.class), serviceConnection, Context.BIND_AUTO_CREATE); 
      Log.i("Service Status: ", "Connected? " + connected); 
     } 
     if (!connected) { 
      throw new RuntimeException("Cannot connect to service"); 
     } 
    } 
} 

回答

3

看起來randomNumberService爲空,當你調用randomNumberService.getRandomNumber();它會拋出空指針異常。

在執行異步任務之前,您應該等到自己的服務已連接好,因爲它取決於您的服務連接。可能提取randomNumberService的服務沒有足夠快地完成,你的Async任務的randomNumberService的有效值不夠快。

+0

雖然它很有趣,但因爲我得到了視圖上更新的隨機數。這個號碼是從其他地方來的嗎? – denniss 2012-03-20 21:36:34

+0

它在您的視圖中顯示-1還是您獲得了您期望的數字? – dymmeh 2012-03-20 21:50:09

+0

另外,您是否嘗試過調試您的應用程序,以查看您的Async任務中的randomNumberService是否爲null。請注意,在Android中調試線程可能有點誤導,因爲如果你的問題是你的Async任務沒有及時獲得變量。由於某些任務需要更長的時間/打斷點等,調試可能會讓它得到變量。 – dymmeh 2012-03-20 21:51:41