Android在Air本地分机调用我的服务之前启动它
我正在为Android开发一个Air(Flex)移动应用程序,它使用Air原生扩展(ANE)来利用一些否则无法使用的平台功能(至少据我所知)。我想使用的平台函数之一是服务,特别是作为前台进程运行的服务(使用startForeground()方法)。 当我从我的电子邮箱调用服务时,一切都像一个符咒一样工作,服务正确启动,它做了它需要做的事情,但问题是Android似乎试图独立于我的代码启动它,这当然会导致日志中出现错误。 当我在Flash Builder中以调试模式启动应用程序,并使用它一段时间检查服务是否正常工作且没有引发错误时,在几秒钟后从Flash Builder(而不是Eclipse ADT,我也可以)关闭它后,会出现以下错误:Android在Air本地分机调用我的服务之前启动它,android,android-intent,android-service,flex-mobile,air-native-extension,Android,Android Intent,Android Service,Flex Mobile,Air Native Extension,我正在为Android开发一个Air(Flex)移动应用程序,它使用Air原生扩展(ANE)来利用一些否则无法使用的平台功能(至少据我所知)。我想使用的平台函数之一是服务,特别是作为前台进程运行的服务(使用startForeground()方法)。 当我从我的电子邮箱调用服务时,一切都像一个符咒一样工作,服务正确启动,它做了它需要做的事情,但问题是Android似乎试图独立于我的代码启动它,这当然会导致日志中出现错误。 当我在Flash Builder中以调试模式启动应用程序,并使用它一段时间检
01-16 10:56:06.953: E/AndroidRuntime(9757): java.lang.RuntimeException: Unable to start service com.mycompany.myextension.services.MyService@41594a50 with Intent { cmp=air.QOE.debug/com.mycompany.myextension.services.MyService }: java.lang.NullPointerException
01-16 10:56:06.953: E/AndroidRuntime(9757): at com.mycompany.myextension.services.MyService.onStartCommand(MyService.java:37)
很明显,Android试图启动该服务,但由于其设计在ANE内工作-扩展已初始化,但其上下文已被释放-它崩溃,因为它无法访问在上下文内初始化的变量,因此,代码第一次使用上下文变量时以崩溃或错误结束(第37行)。
我认为这与我在Android清单文件中声明服务的方式有关。接下来是XML的一部分:
<application android:debuggable="true">
<service android:enabled="true" android:exported="true" android:name="com.mycompany.myextension.services.MyService">
<intent-filter>
<action android:name="air.com.mycompany.myextension.DO_CUSTOM_ACTION"/>
</intent-filter>
</service>
</application>
当手机内存不足并在完成执行之前终止服务时
START\u STICKY
告诉操作系统在拥有足够内存后重新创建服务,并再次以空意图调用onStartCommand()START\u NOT\u STICKY
告诉操作系统不要再费心重新创建服务。还有第三个代码START\u REDELIVER\u INTENT
,它告诉操作系统重新创建服务并将相同的意图重新交付到onStartCommand()
我有一个使用
START\u STICKY
的电子邮件,它一直在启动该服务您是否注册了任何广播接收器来启动该服务?@Delcasda,没有。我正在从本机函数
启动该服务,调用startService()
。在onStartCommand()
中,我正在使用startForeground()
。因此,没有使用广播接收器。还有其他想法吗?你是在使用return START\u STICKY;在onStartCommand?这使得服务可以自动启动,但如果您在least@Delcasda. 是的,我确实使用了START\u STICKY
atonstart命令?
。你建议我怎么做。我编辑了帖子并添加了服务代码。我认为这是正确的,但我只有一个问题。当重新创建服务时,在服务被销毁之前(由于内存问题)创建的变量、属性和任务会发生什么情况?它们开始时是空的,还是一切都会像以前一样?onCreate()
方法是否在onStartCommand()
之前再次调用?我不知道,但您可以很容易地找到覆盖onCreate方法并添加以下内容:Toast.makeText(这是“创建时服务开始”,Toast.LENGTH\u SHORT).show();如果您认为这是答案,请将其标记为已接受答案。要回答我的问题,它确实会在调用onstart命令()
之前调用onCreate()
,然后在由于内存问题而被销毁后重新创建。至少我的日志显示了这一点。谢谢你的帮助。你认为你可以看看这个答案提出的问题吗?:)
package com.mydomain.myapplicationextension.services;
import java.util.Timer;
import com.adobe.fre.FREContext;
import com.mydomain.myapplicationextension.myapplicationextension;
import com.mydomain.myapplicationextension.components.HttpServiceTask;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class MyApplicationService extends Service {
private Timer timer;
@Override
public IBinder onBind(Intent arg0) {
// Log.d("MyApplicationService", "onBind()");
return null;
}
@Override
public void onCreate() {
// Log.d("MyApplicationService", "onCreate()");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Log.d("MyApplicationService", "onStartCommand(): " + myapplicationextension.applicationID);
Context appContext = myapplicationextension.applicationContext;
Intent launchIntent = appContext.getPackageManager().getLaunchIntentForPackage(myapplicationextension.appPackageName);
PendingIntent pendingLaunchIntent = PendingIntent.getActivity(appContext, 0, launchIntent, 0);
FREContext extContext = myapplicationextension.extensionContext;
int icon = extContext.getResourceId("drawable.notification_icon");
Notification notification = new Notification.Builder(appContext)
.setContentTitle(myapplicationextension.applicationID)
.setContentText(myapplicationextension.notificationMessage)
.setSmallIcon(icon)
.setContentIntent(pendingLaunchIntent)
.build();
startForeground(1,notification);
// Log.d("MyApplicationService", "startForegroundService()");
if(myapplicationextension.checkStatus)
{
timer = new Timer("Printer");
HttpServiceTask serviceTask = new HttpServiceTask(timer, launchIntent,myapplicationextension.statusServiceURL, myapplicationextension.triggerResponse);
timer.schedule(serviceTask, 0, 2000);
// Log.d("MyApplicationService", "startTimer()");
}
return START_STICKY;
}
@Override
public void onDestroy() {
// Log.d("MyApplicationService", "onDestroy():");
if(myapplicationextension.checkStatus)
{
timer.cancel();
timer = null;
// Log.d("MyApplicationService", "onDestroy(): timer.cancel():");
}
super.onDestroy();
}
}