【问题标题】:Android Services安卓服务
【发布时间】:2011-09-01 13:11:22
【问题描述】:

我正在为 android 编写一个 Web 服务器。实际上它适用于线程,但现在我将使用服务使其在后台运行。把线程换成服务了,不知道这样的设计好不好…… 当我按下一个按钮时,它会启动,然后它会一直在听。当有请求时,服务会创建一个线程来服务它。 这是我的结构:

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

问题出在哪里?

【问题讨论】:

    标签: java android sockets webserver android-service


    【解决方案1】:

    你看过this的帖子吗?它基本上说您的构造函数中有错误。他的解决方法是删除参数,并确保调用超级的构造函数......

    InstantiationException 当异常被抛出时发生 构造函数。通常应该有另一个异常报告为 导致 InstantiationException,堆栈跟踪应该指向 到错误的特定行。堆栈跟踪是你的朋友, 你应该感激——他们是编程的可怜的孩子 没有堆栈跟踪的 Symbian 设备。

    【讨论】:

    • 我的问题是我应该同时扩展服务和网络服务器,但由于不可能,我想知道我的解决方案在概念上是否正确。我看到了那篇文章,但它似乎与我的设计不同。而且,就我而言,我必须将参数传递给构造函数
    【解决方案2】:

    您是否在子类(WerServer 或 DroidServer)中实现了回调方法 onStartCommand()?详情请查看Service.startService()

    就个人而言,我认为在您的设计中使用绑定形式的服务更合理,您可以将 is-a 关系替换为 has-a 关系。

    您的网络服务器:

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

    }

    在您的 Activity 中,像这样使用您的 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 );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 2013-03-31
      • 2015-08-16
      • 1970-01-01
      相关资源
      最近更新 更多