着手改造以前,有興趣能夠閱讀下官方文檔:http://help.adobe.com/zh_CN/air/extensions/index.htmlhtml
新建工程 NavService 並建立包 nav.wenbo.service, 這些均可以自定義,但要記住你的包名。java
注意最下方那個jar包,這個是必需的,打開項目的構建目錄(buildPath),引用外部jar包, 目錄在你在Flex sdk目錄下android
%FlexSDK%\4.x.x\lib\android\FlashRuntimeExtensions.jarapp
個人本地目錄是:F:\Program Files\Adobe\Adobe Flash Builder 4.7\sdks\4.6.0\lib\android\FlashRuntimeExtensions.jaride
首先建立air調用的入口類 ServiceExtension 這個類必需在ane包裏面的extension.xml裏指定(後面會介紹)ui
package nav.wenbo.service; import android.content.Context; import android.content.Intent; import android.util.Log; import com.adobe.fre.FREContext; import com.adobe.fre.FREExtension; public class ServiceExtension implements FREExtension { public static final String TAG = "ServiceExtension"; public static Context appContext; public static FREContext extensionContext; public static String Msg = "none"; @Override public FREContext createContext(String contextType) { // TODO Auto-generated method stub return new ServiceExtensionContext(); } @Override public void dispose() { // TODO Auto-generated method stub Log.d(TAG, "Extension disposed."); } @Override public void initialize() { // TODO Auto-generated method stub Log.d(TAG, "Extension initialized."); } }
ServiceExtension中關鍵是 createContext 方法,這個方法返回一個可連通air及本地Java代碼的上下文。並在該上下文中定義可供air調用的方法。this
下面是ServiceExtensionContext類spa
package nav.wenbo.service; import java.util.HashMap; import java.util.Map; import nav.wenbo.service.functions.InitFunction; import nav.wenbo.service.functions.SendFunction; import nav.wenbo.service.functions.StartFunction; import android.util.Log; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; public class ServiceExtensionContext extends FREContext { public static final String TAG = "ServiceExtensionContext"; @Override public void dispose() { // TODO Auto-generated method stub Log.d(TAG,"Context disposed."); } @Override public Map<String, FREFunction> getFunctions() { Map<String, FREFunction> functions = new HashMap<String, FREFunction>(); functions.put("init", new InitFunction()); functions.put("service", new StartFunction()); functions.put("send", new SendFunction()); return functions; } }
functions.put至關注冊調用邏輯的調用名, 這裏把你全部調用方法都填上。init 用於初始化上下文,service用來啓動和關閉服務, send用於發送消息。 在編寫對應方法以前,code
先把上一節的Backgroundservice 移植過來xml
package nav.wenbo.service; import com.wenbo.navservice.R; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class NotificationService extends Service { private NotificationManager notificationMgr; private Thread mthr; private int mCount=0; private Boolean mSend=true; @Override public void onCreate() { super.onCreate(); notificationMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); displayNotificationMessage("starting Background Service"); if(mthr == null || mSend == false) { mSend=true; mthr = new Thread(null, new ServiceWorker(), "BackgroundSercie"); mthr.start(); } if(null != ServiceExtension.extensionContext) ServiceExtension.extensionContext.dispatchStatusEventAsync("start", "1"); } @Override public void onDestroy() { super.onDestroy(); mSend = false; } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } class ServiceWorker implements Runnable { @Override public void run() { // do background processing here..... // stop the service when done... // BackgroundService.this.stopSelf() while(mSend) { try{ Thread.sleep(1000); Log.d("", "runnable" + mCount); displayNotificationMessage(ServiceExtension.Msg); } catch (InterruptedException e) { e.printStackTrace(); } } } } private void displayNotificationMessage(String message) { if(message == "none") return; Log.d("", message); mCount++; Notification notification = new Notification(R.drawable.ic_launcher, message, System.currentTimeMillis()); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Activity.class), 0); notification.setLatestEventInfo(this, "女神之賤", message, contentIntent); notificationMgr.notify(1000, notification); } }
這裏改動很小,發送的消息從ServiceExtension類裏面取,當message != none時顯示該通知,另ServiceExtension.extensionContext.dispatchStatusEventAsync 是用來給air程序發消息, 在air中監聽StatusEvent.STATUS 能夠捕獲這條消息並獲取對應參數。在這裏用處是通知服務啓動成功。
下面就剩下實際調用的方法了。
首先是初始化上下文,這裏主要是ServiceExtension.extensionContext 主要用於往air發消息。
package nav.wenbo.service.functions; import nav.wenbo.service.ServiceExtension; import android.content.Context; import android.util.Log; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; import com.adobe.fre.FREObject; public class InitFunction implements FREFunction { public static final String TAG = "InitFunction"; @Override public FREObject call(FREContext context, FREObject[] args) { ServiceExtension.extensionContext = context; Context appContext = context.getActivity().getApplicationContext(); ServiceExtension.appContext = appContext; Log.i(TAG, "in init"); return null; } }
這裏注意了,由於咱們沒有獨立的Android入口文件,咱們 只能從 FREContext.getActivity() 來取得咱們所需的上下文,並用這上下文啓動咱們的服務,這是跟前一節例子最大不一樣的地方。
執行後通知air:context.dispatchStatusEventAsync("start", "2");
package nav.wenbo.service.functions; import nav.wenbo.service.NotificationService; import android.content.Context; import android.content.Intent; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; import com.adobe.fre.FREObject; public class StartFunction implements FREFunction { @Override public FREObject call(FREContext context, FREObject[] args) { Context appContext = context.getActivity().getApplicationContext(); Boolean isStart=true; try { isStart = args[0].getAsBool(); } catch (Exception e) { } if(isStart) context.getActivity().startService(new Intent(appContext, NotificationService.class)); else context.getActivity().stopService(new Intent(appContext, NotificationService.class)); context.dispatchStatusEventAsync("start", "2"); return null; } }
最後這個最簡單,僅僅設置下所要推送的消息.
package nav.wenbo.service.functions; import nav.wenbo.service.ServiceExtension; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; import com.adobe.fre.FREObject; public class SendFunction implements FREFunction { @Override public FREObject call(FREContext context, FREObject[] args) { // TODO Auto-generated method stub String msg="none"; try { msg = args[0].getAsString(); } catch(Exception e) { } ServiceExtension.Msg = msg; return null; } }
作完這些,並設置好權限後,把項目導出jar包, 命名爲 libAndroidServiceLib.jar
下一節我將介紹air中跟此jar包對接。