安卓运行时异常:无法实例化服务

48

我想创建一个在单独线程上运行的服务(不是在UI线程上),因此我实现了一个继承IntentService的类。但是我没有成功。以下是代码。

public class MyService extends IntentService {

    public MyService(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        Log.e("Service Example", "Service Started.. ");
        // pushBackground();

    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        Log.e("Service Example", "Service Destroyed.. ");
    }

    @Override
    protected void onHandleIntent(Intent arg0) {
        // TODO Auto-generated method stub
        for (long i = 0; i <= 1000000; i++) {
            Log.e("Service Example", " " + i);
            try {
                Thread.sleep(700);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

在 Activity 按钮点击时进行服务消费:

public void onclick(View view) {
Intent svc = new Intent(this, MyService.class);
    startService(svc);
}

请查看示例:http://developer.android.com/reference/android/app/Service.html#LocalServiceSample - Peter Knego
5
你提供的例子是一个 Service 而不是一个 IntentService - james
5个回答

68

在你的具体实现中,你需要声明一个默认构造函数,该函数调用你所继承的抽象IntentService类的public IntentService(String name)超级构造函数:

public MyService () {
  super("MyServerOrWhatever");
}

如果父类的onStartCommand实现适合你,那么你就不需要覆盖它(这是我期望的)。

在您当前的情况下,应该会出现异常(无法实例化服务...)- 将其放入问题中总是值得的。


4
这里并不是这种情况,但这可能会帮助某些人: 检查您的服务类是否不是抽象的。我遇到了这个问题,因为我复制了SDK中的IntentService实现,并修改它以更好地适应我的需求。

我曾经遇到过同样的问题,但在自己调试之前我没有注意到这个答案。@Juuso,我编辑了你的回复并加入了一些代码,使其更加明显。 - user2768

1

ServiceDemo.java:

public class ServicesDemo extends Activity implements OnClickListener {
  private static final String TAG = "ServicesDemo";
  Button buttonStart, buttonStop;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    buttonStart = (Button) findViewById(R.id.buttonStart);
    buttonStop = (Button) findViewById(R.id.buttonStop);

    buttonStart.setOnClickListener(this);
    buttonStop.setOnClickListener(this);
  }

  public void onClick(View src) {
    switch (src.getId()) {
    case R.id.buttonStart:
      Log.w(TAG, "onClick: starting srvice");
      startService(new Intent(this, MyService.class));
      startActivity(new Intent(getApplicationContext(),Second.class));
      break;
    case R.id.buttonStop:
      Log.w(TAG, "onClick: stopping srvice");
      stopService(new Intent(this, MyService.class));
      break;
    }
  }
}

MyService.java:

package com.example;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class MyService extends Service {
    private static final String TAG = "MyService";
    MediaPlayer player;

    @Override
    public IBinder onBind(Intent intent) {
        Log.w(" ibinder ","");
        return null;
    }

    @Override
    public void onCreate() {
        Toast.makeText(this, "My Service Created",0).show();
        Log.w(TAG, "onCreate");

        player = MediaPlayer.create(this,R.raw.frm7v1);
        player.setLooping(true); // Set looping
    }



    @Override
    public void onDestroy() {
        Toast.makeText(this, "My Service Stopped",0).show();
        Log.w(TAG, "onDestroy");
        player.stop();
    }

    @Override
    public void onStart(Intent intent, int startid) {
        Toast.makeText(this, "My Service Started :"+intent+" start id :"+startid,0).show();
        Log.d(TAG, "onStart");
        player.start();
    }
}

在清单文件中声明以下属性:

  <service android:enabled="true" android:name=".MyService" />

9
这是一个好的服务示例,但不是问题所问的IntentService。 - MSpeed

1

此答案已更新。以下是更新后的正确答案:

根据文档,您不必为IntentServices覆盖onStartCommand()方法,相反,文档对于IntentServices的onStartCommand()方法有以下说明:您不应该为IntentService覆盖此方法。相反,覆盖onHandleIntent(Intent)方法,当IntentService接收到启动请求时系统会调用该方法。(感谢Ready4Android)。


以下是原始的错误答案(保留以便评论有意义):

根据文档,您应该重写OnStartCommand()(或已弃用的OnStart())以处理意图服务的启动。您试过了吗?正如K. Claszen所写 - 您需要实现默认构造函数。


3
根据文档,对于INTENTService,您不需要覆盖onStartCommand()方法。相反,文档指出对于IntentServices的onStartCommand()应该如下:不应该覆盖此方法。而是要覆盖onHandleIntent(Intent)方法,在IntentService接收到启动请求时系统会调用此方法。 - Ready4Android
1
@Ready4Android 你说得对,我会编辑我的答案,以免让其他人感到困惑。谢谢。 - Audrius

1
我通过添加默认的无参构造函数解决了“无法实例化服务”的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接