【问题标题】:Android RuntimeException: Unable to instantiate the serviceAndroid RuntimeException:无法实例化服务
【发布时间】:2011-06-28 23:14:18
【问题描述】:

我想创建一个将在单独的线程(而不是 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);
}

【问题讨论】:

标签: android android-service android-intentservice


【解决方案1】:

在您的具体实现中,您必须声明一个默认构造函数,该构造函数调用您扩展的抽象 IntentService 类的 public IntentService (String name) 超级构造函数:

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

如果超级实现适合您(我所期望的),您不需要覆盖 onStartCommand。

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

【讨论】:

    【解决方案2】:

    这里不是这样,但这可能对某人有帮助: 检查您的服务类不是抽象的。我遇到了这个问题,因为我从 SDK 复制了 IntentService 实现并对其进行了修改以更好地满足我的需求。

    【讨论】:

    • 我遇到了同样的问题,但直到我自己调试后才注意到这个答案。 @Juuso,我已经编辑了您的回复以包含一些代码,从而使其更加明显。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      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" />
      

      【讨论】:

      • 这是一个很好的服务示例,但不是问题所问的 IntentService。
      【解决方案5】:

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

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


      以下是原来的错误答案(留下来让 cmets 有意义):

      根据documentation,您应该重写 OnStartCommand()(或不推荐使用的 OnStart())以处理 Intent 服务启动。你试过了吗?正如K. Claszen 所写 - 您需要实现默认构造函数。

      【讨论】:

      • 根据文档,您不必为 INTENTServices 重写 onStartCommand(),相反,文档对 IntentServices 的 onStartCommand() 进行了以下说明:您不应该为您的 IntentService 重写此方法。而是重写 onHandleIntent(Intent),当 IntentService 收到启动请求时系统调用它。
      • @Ready4Android 你是对的,我会编辑我的答案,以免混淆其他人。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多