服务正在启动,但未调用OnCreate或OnStart。

6

我目前正在进行一项安卓项目,我正在尝试启动一个服务,并在服务开始运行时初始化一些东西。

下面是我用于服务的代码:

Context context;
    PowerManager.WakeLock wakeLock;

    public PowerDetectionService(Context context)
    {
        this.context = context;
    }

    public PowerDetectionService()
    {}

    public void onCreate()
    {
        super.onCreate();
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
    }

    public void onStart(Intent intent, int startId)
    {
        super.onStart(intent, startId);
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
    }

    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

    public void receivedPowerConnected()
    {
        try
        {
            Toast.makeText(context, "Power connected", Toast.LENGTH_LONG).show();
            wakeLock.acquire();
        }
        catch (Exception ex)
        {
            Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
        }
    }

    public void receivedPowerDisconnected()
    {
        try
        {
            Toast.makeText(context, "Power disconnected", Toast.LENGTH_LONG).show();
            wakeLock.release();
        }
        catch (Exception ex)
        {
            Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
        }
    }

唤醒锁始终为null,因为该代码段从未在oncreate或onstart中执行。我尝试将其放入bind函数中,但仍然无法解决问题。
当我进入Android设置时,我可以看到我的应用程序正在运行服务,但我需要在任何操作之前初始化该代码。
感谢您提供的任何帮助。
更新:我已经发现函数被调用了,感谢上一个评论。由于某种原因,调试器没有启动。
以下是请求创建服务器的代码。
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startService(this);
}

public void onResume()
{
    super.onResume();
    startService(this);
}

private void startService(Context context)
{
    Intent service = new Intent(context, PowerDetectionService.class);
    context.startService(service);
}

更新2 如下所请求,这是启动服务和执行唤醒锁的所有代码。

以下是启动服务的主要活动。

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        StartPowerService(this);
        //getActionBar().setDisplayHomeAsUpEnabled(true);
    }

    public void onResume()
    {
        super.onResume();
        StartPowerService(this);
    }

    private void StartPowerService(Context context)
    {
        Intent service = new Intent(context, PowerDetectionService.class);
        startService(service);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            //case android.R.id.home:
            //    NavUtils.navigateUpFromSameTask(this);
            //    return true;
        }
        return super.onOptionsItemSelected(item);
    }

}

以下是服务类的代码:
public class PowerDetectionService extends Service {

    Context context;
    PowerManager.WakeLock wakeLock;

    public PowerDetectionService(Context context)
    {
        this.context = context;
    }

    public PowerDetectionService()
    {}

    public void onCreate()
    {
        super.onCreate();
        Log.d("SERVICE", "ON CREATE CALLED");
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
    }

    public int OnStartCommand(Intent intent, int flags, int startId)
    {
        Log.d("SERVICE", "ONSTARTCOMMAND Called");
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
        return START_STICKY;
    }

    public void onStart(Intent intent, int startId)
    {
        super.onStart(intent, startId);
        Log.d("SERVICE", "ON START CALLED");
        PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ScreenStay");
    }

    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

    public void receivedPowerConnected()
    {
        try
        {
            Toast.makeText(context, "Power connected", Toast.LENGTH_LONG).show();
            wakeLock.acquire();
        }
        catch (Exception ex)
        {
            Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
        }
    }

    public void receivedPowerDisconnected()
    {
        try
        {
            Toast.makeText(context, "Power disconnected", Toast.LENGTH_LONG).show();
            wakeLock.release();
        }
        catch (Exception ex)
        {
            Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
        }
    }
}

以下是主文件清单。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.BoardiesITSolutions.ScreeenStay"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="PowerDetectionService"
            android:process=":ScreenStay"
            android:icon="@drawable/ic_launcher"
            android:label="Screen Stay">
        </service>
        <receiver android:name="BroadcastReceiveDetection">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

希望这有所帮助。

你确定你的onCreate()和onStart方法没有被调用吗?你的唤醒锁可能因为其他原因为空。 - Amokrane Chentir
我在它们两个上都设置了断点,但它们从未被触发。但是我刚刚在代码中加入了Log.d来确保,但它们确实被打印出来了。为什么它会是null呢? - Boardy
你能展示一下如何启动服务吗? - Orabîg
我已按要求添加了代码。 - Boardy
3个回答

9
您正在不同的进程中启动服务。
    <service android:name="PowerDetectionService"
        android:process=":ScreenStay"
        android:icon="@drawable/ic_launcher"
        android:label="Screen Stay">

调试器已连接到您的主进程。当新进程启动时,它没有连接调试器,因此会忽略您的断点。如果您想调试远程进程,则可以通过Eclipse中的DDMS透视图来完成。在设备下面,您可以看到它的进程。然后您可以选择一个并按“调试所选进程”(绿色虫子图标)。这对于仅想在某一点开始调试应用程序的情况也很有用。
至于调试onCreate(),您必须在进程启动后但在调用onCreate()之前附加调试器。例如,您可以在onCreate()的开头放置一些Thread.sleep()几秒钟,以便您可以附加调试器。

3

您正在扩展哪个类?是Service类吗?

onStart()方法仅用于旧版Android(<2.0)。对于更近期的版本,您应该使用以下onStartCommand()方法:

@Override
public int onStartCommand(Intent intent, int flags, int startId)

如果你希望服务在执行代码后继续运行,需要在上面的方法中返回START_STICKY。如果服务没有保持活动状态,PowerManager.FULL_WAKE_LOCK将被释放。可能你还可以通过将wakeLock设置为静态来解决问题。

要启动服务,请使用以下命令:

    Intent i=new Intent(this, PowerDetectionService.class);
    startService(i);

根据这里的主题:getApplication() vs. getApplicationContext(),使用getApplicationContext()获取上下文时可能会获得不同的Context对象。请尝试更改以下行:
    PowerManager pm = (PowerManager)getApplication().getApplicationContext().getSystemService(Context.POWER_SERVICE);

by:

    PowerManager pm = (PowerManager)this.getSystemService(Context.POWER_SERVICE);

regrads.


谢谢尝试,但这并没有被执行,我已经放置了一个Log.d,但是没有输出,只有onCreate被调用。 - Boardy
你如何启动服务? - Luis
我已经在我的回答中添加了如何启动服务的内容。 - Luis
这就是我正在做的事情,服务已经启动,但唤醒锁始终为空。 - Boardy
你是否在 AndroidManifest.xml 中添加了 android.permission.WAKE_LOCK 权限? - Luis
显示剩余12条评论

0

温馨提示:

onStart() 方法已被废弃,您应该使用 onStartCommand() 代替(只会在通过 Context.startService() 启动服务时调用)。

然而,如果您的服务确实运行,onCreate() 应该仍然会被调用(但只会调用一次)。


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