Android在Air原生扩展调用它之前启动我的服务

时间:2014-01-16 14:22:20

标签: android android-intent android-service flex-mobile air-native-extension

我正在为Android开发Air(Flex)移动应用程序,该应用程序使用Air Native Extension(ANE)来利用一些本来无法使用的平台功能(至少据我所知)。我想要使​​用的平台函数之一是服务,特别是作为Foreground进程运行的服务(使用startForeground()方法)。 当我从我的ANE调用服务时,一切都像魅力一样,服务正确启动,它完成了它需要做的事情,但问题是Android似乎试图独立于我的代码启动它,当然,导致LogCat中出现错误。 当我在Flash Builder中以调试模式启动应用程序时,我使用它一段时间检查服务是否完美运行并且没有错误,在我从Flash Builder关闭它之后(不是从Eclipse ADT,我也可以)几秒钟后,出现以下错误:

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 Manifest文件中声明服务的方式有关。接下来是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>

我希望你能告诉我,我是否错误地宣布了服务,或者我是否在其他地方犯了错误。我很感激帮助。

编辑:服务代码

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

1 个答案:

答案 0 :(得分:1)

当手机内存不足并在服务完成之前终止服务时。 START_STICKY告诉操作系统在有足够内存后重新创建服务,并再次使用null intent调用onStartCommand()。 START_NOT_STICKY告诉操作系统不要再次重新创建服务。还有第三个代码START_REDELIVER_INTENT告诉操作系统重新创建服务并将同一意图重新传递给onStartCommand()

START_STICKY and START_NOT_STICKY

我有一个使用START_STICKY的ANE继续启动服务