安卓服务

发布于 2024-12-02 14:47:55 字数 2130 浏览 1 评论 0原文

我正在为 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

问题出在哪里?

I'm writing a web server for android. Actually it works with threads, but now I would use a service to make it running in background. I replaced the thread with a service, but I don't know if this design is ok...
When I press a button it starts then it stays in listening. When there is a request, the service create a thread to serve it.
This is my structure:

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'/> ...

But when I click on the button I get this exception:

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

Where's the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

没有你我更好 2024-12-09 14:47:55

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

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

Have you seen this post? It basically says there is an error in your constructor. His fix was to remove the argument, and also make sure to call the super's constructor ...

InstantiationException occurs when an exception is thrown out of a
constructor. Generally there should be another exception reported as
causing the InstantiationException, and the stack trace should point
to the specific lines that are in error. Stack trace is your friend,
and you should be grateful -- their are poor children programming on
Symbian devices who have no stack trace.

夜声 2024-12-09 14:47:55

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

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

您的 WebServer:

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

Did you implement the callback method onStartCommand() in your subclass (either WerServer or DroidServer)? Check out Service.startService() for details.

Personally, I think use the bound form of service is more reasonable in your design, where you can replace a is-a relationship with a has-a relationship.

Your WebServer:

class WebServer implements IWebServer {
  doSoming();
}

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

}

In your Activity, use your DroidServer like this:

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 );
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文