2011-09-01 76 views
1

我正在爲android編寫一個web服務器。實際上它可以和線程一起工作,但現在我會使用一種服務使它在後臺運行。我用一個服務替換了線程,但是我不知道這個設計是否正確... 當我按下一個按鈕時,它會啓動,然後它仍然在監聽。當有請求時,服務創建一個線程來提供服務。 這是我的結構:Android服務

WebServer.java

class WebServer extends Service{ 
onCreate(){...} 
onDestroy(){...} 
} 

DroidServer.java

class DroidServer extends WebServer{...} 

MyActivity.java

MyActivity extends Activity{ 
boolean isOn=false; 
btn.setOnClickListener(new OnClickListener(){ 
public void onClick(View V){ 
    if(!isOn){ 
    startService(new Intent(this, DroidWebServer.class)); 
    btn.setText("Stop"); 
    }else{ 
    stopService(new Intent(this, DroidWebServer.class)); 
    btn.setText("Start"); 
    }}}); 
} 

AndroidManifest.xml中

... <service android:name='DroidWebServer'/> ... 

但是當我按一下按鈕我得到這個異常:

FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to Instantiate service it.giox.ws.DroidWebServer: java.lang.InstantiationException: it.giox.ws.DroidWebServer 
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:1933) 
    at android.app.ActivityThread.access$2500(ActivityThread.java:117) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:985) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:123) 
    at android.app.ActivityThread.main(ActivityThread.java:3729) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:507) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:874) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:632) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.InstantiationException: it.giox.ws.DroidWebServer 
    at java.lang.Class.newInstanceImpl(Native Method) 
    at java.lang.Class.newInstance(Class.java:1409) 
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:1930) 
    ... 10 more 

在哪裏的問題?

回答

2

你見過this嗎?它基本上說你的構造函數有一個錯誤。他的修復是去除的說法,也請確保調用超級的構造......當異常被拋出一個 構造發生

InstantiationException。通常應該有另外一個異常報告爲 導致InstantiationException,並且堆棧跟蹤應該指向 到錯誤的特定行。堆棧跟蹤是你的朋友, ,你應該感激 - 他們是可憐的孩子編程 沒有堆棧跟蹤的Symbian設備。

+0

我的問題是我應該延伸這兩種服務和網絡服務器,但因爲這是不可能的,所以我想知道我的解決方案在概念上是否正確。我看到那篇文章,但它似乎不同於我的設計。而且,在我的情況下,我必須將參數傳遞給構造函數 – supergiox

0

您是否在子類(WerServer或DroidServer)中實現了onStartCommand()回調方法?詳情請查閱Service.startService()

就我個人而言,我認爲在您的設計中使用綁定形式的服務更合理,您可以用一個has-a關係替換is-a關係。

你的web服務器:

class WebServer implements IWebServer { 
    doSoming(); 
} 

你DroidServer:

class DroidServer extends Service { 
    private WebServer webServer; 
    private WebServerBinder myBinder; 

    onCreate(){...} 

    IBinder onBind(Intent intent) { 
    return myBinder; 
    } 

    onDestroy(){...} 

    protected class WebServerBinder extends Binder implements IWebServer { 
    doSomething() { 
     myServer.doSomething(); 
    } 
    } 

}

在你的活動,用你的DroidServer這樣的:

public class MyActivity extends Activity { 
    private IWebServer myWebService; 

    private ServiceConnection myServiceConnection = new ServiceConnection() { 
    public void onServiceConnected(ComponentName className, IBinder service) { 
     myWebService = (IWebServer) service; 
    } 

    public void onServiceDisconnected(ComponentName className) { 
     if (myWebService != null) 
     myWebService = null; 
    } 
    }; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    bindService(new Intent(this, DroidWebServer.class), 
     myServiceConnection, Context.BIND_AUTO_CREATE); 

    boolean isOn=false; 
    btn.setOnClickListener(new OnClickListener(){ 
     public void onClick(View V){ 
     if(!isOn){ 
      myWebService.doSomething(); 
      btn.setText("Stop"); 
     }else{ 
      myWebService.doSomethingElse(someParam); 
      btn.setText("Start"); 
     }}}); 
    } 

    @Override 
    public void onDestroy() { 
    super.onDestroy(); 
    unbindService(myServiceConnection); 
    } 
}