守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 3521|回复: 3

[Android] 使用NativeExtension向AIR app 添加Activity和BroadCastReceiver

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51753
    钢镚
    1422

    开源英雄守望者

    发表于 2015-1-10 21:56:23 | 显示全部楼层 |阅读模式
    前言

    AIR3NativeExtension提供的让AIR调用本地代码的功能,从而将一些Actionscript无法做到的功能用系统的本地代码来实现。

    目前大部分NativeExtension应用主要是将需要实现的功能封装为一个本地函数,然后通过AIR runtime调用这个本地函数实现AIR无法完成的功能,或者提升该功能的性能。如对振动器的调用。其实,NativeExtension不仅仅可以进行函数层级上的扩展,对GUI部分也可以进行扩展,本篇文章就以在Android平台为例,向AIR开发的app添加ActivityBroadCastReceiver 这样,使用AIR开发的app不仅可以超出原有AIR的显示框架,而且可以接受系统广播事件,从而完成以前无法完成的很多功能,开发出更加丰富多彩的应用。最简单的例子就是可以直接调用Android系统的Camera了,这样可以实现自动对焦的一些功能。

    这篇教程主要会演示如使用NativeExtensionAIR app中添加ActivityBroadCastReceiver。希望能给大家的NativeExtension开发提供更多的思路。

    由于NativeExtension的开发目前来讲不论是开发还是部署打包都是一个比较复杂的工作,很容易做错步骤,因此希望大家先在看这篇之前,先参考:http://sswilliam.blog.163.com/blog/static/189696383201191094227313/这一系列教程,以了解NativeExtension开发的一些基本操作。

    Demo简介

    为了让大家更好的理解要做的事情,在这里将我们的demo做一个简单的介绍。Demo的示意图如下:


    其大体流程是AIR app会启动一个Android原生的Activity,然后在原生的Activity进行一些逻辑处理后,将结果返回给AIR



    1.开启应用,点击call activity按钮


    2.系统弹出我们在NativeExtension中用Java写的原生的Activity


    3. 我们在输入框中输入一些字符后点击return



    4.
    通过IntentActivity的结果返回给AIR

    其实这个流程在Android原生开发中非常常见,就是调用ActivitystartActivityForResult方法,然后重写一下onActivityResult方法就能接收到返回的结果。但是这个流程在AIRApp中行不通,因为AIRapp中的主要的Activity是由AIR SDK生成的AppEntry,我们无法对其中的方法进行重写,只能通过FREContextgetActivity()来获取其引用。所以我们会创建一个BroadcastReceiver,使用Android系统的广播机制将我们所需要的值进行返回并做相应处理,然后NativeExtension会将返回值以事件抛回AIR app,从而完成整个流程。

    其中主要涉及的重点包括:

    FREContext的使用

    如何从NativeExtension中向AIR抛出事件

    AIRapp.xml的配置



    本系列文章来自:http://sswilliam.blog.163.com/blog/static/18969638320119285102604/

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51753
    钢镚
    1422

    开源英雄守望者

     楼主| 发表于 2015-1-10 21:59:48 | 显示全部楼层
    开发:Android项目

    新建一个针对NativeExtensionAndroid项目,实现相应的FREContextFREExtensionFREFunction等方法,同时新建一个Activity和一个BroadCastReceiver。对于如何配置Android项目来开发NativeExtension,参考http://sswilliam.blog.163.com/blog/static/1896963832011910101142574/

    Android项目目录和代码如下:




    CallBackExtension

    CallBackExtensionNativeExtension的入口,实现了FREExtension接口,直接返回一个CallBackContext的对象实例,没啥好说的

    1. package net.sswilliam.ane.callback;

    2. import com.adobe.fre.FREContext;
    3. import com.adobe.fre.FREExtension;

    4. public class CallBackExtension implements FREExtension {

    5.       @Override
    6.       public FREContext createContext(String arg0) {
    7.             // TODO Auto-generated method stub
    8.             return new CallBackContext();
    9.       }

    10.       @Override
    11.       public void dispose() {
    12.             // TODO Auto-generated method stub

    13.       }

    14.       @Override
    15.       public void initialize() {
    16.             // TODO Auto-generated method stub

    17.       }

    18. }
    复制代码

    CallBackContext

    CallBackContext是整个扩展Java部分的上下文,扩展了FREContext。首先先定义一些常量:

    常量名
    说明
    REGISTER_RECEIVER_FUNCTION
    注册BroadCastReceiver函数的Key
    START_ACTIVITY_FUNCTION
    开启Activity函数的Key
    DATA_RECEIVE
    返回给AS端的事件

    CallBackContext中主要需要实现getFunctions()方法,用来返回具体的java函数的映射:

    1.    @Override
    2.       public Map<String, FREFunction> getFunctions() {
    3.             // TODO Auto-generated method stub
    4.             if(functionMaps == null){
    5.                   functionMaps = new HashMap<String, FREFunction>();
    6.                   functionMaps.put(REGISTER_RECEIVER_FUNCTION, new RegisterReceiverFunction());
    7.                   functionMaps.put(START_ACTIVITY_FUNCTION, new StartActivityFunction());
    8.             }
    9.             return functionMaps;
    10.       }
    复制代码

    RegisterReceiverFunction

    RegisterReceiverFunction实现了FREFunction接口。其功能是向Android系统注册一个BroadCastReceiver。这里我们直接通过registerReceiver函数动态注册BroadCastReceiver而非是在AndroidManifest.xml中静态注册,主要原因是这个BroadCastReceiver的生命周期也就是这个app的生命周期,并且需要与AppFREContext进行交互,注册为静态的不是很合适。当然在AIR开发的Android程序中,也是支持在AndroidManifest.xml中静态注册BroadCastReceiver的。我们会在后面静态的注册一个Activity,静态注册BroadCastReceiver的方法和注册Activity的方法一样,因此这里就不赘述了。就像正常Android程序开发一样,Log也适用于AIR开发的Android app,可以在Logcat中查看。

    1. @Override
    2.       public FREObject call(FREContext arg0, FREObject[] arg1) {
    3.             // TODO Auto-generated method stub
    4.             Log.d("YZ", "register receiver");
    5.             MyReceiver receiver = new MyReceiver(arg0);
    6.             arg0.getActivity().registerReceiver(receiver, new IntentFilter(MyReceiver.MYARECEIVER_ACTION));
    7.             return null;
    8.       }
    复制代码

    StartActivityFunction

    StartActivityFunction实现了FREFunction接口。其功能是打开一个我们自定义的Activity。我们会定义一个自定义的ACTION。然后在AndroidManifest.xml将这个ACTION和这个Activity进行绑定。这样我们用startActivity方法发送一个Intent,就可以开启这个Activity

    1. @Override
    2.       public FREObject call(FREContext arg0, FREObject[] arg1) {
    3.             // TODO Auto-generated method stub
    4.             Intent intent = new Intent(MyActivity.MYACTIVITY_ACTION);
    5.             arg0.getActivity().startActivity(intent);
    6.             return null;
    7.       }
    复制代码

    MyActivity

    MyActivity就是我们自定义的用来返回结果的Activity。首先会定义MyActivity的开启的ACTIONMYACTIVITY_ACTION = "net.sswilliam.ane.callback.myactivity".

    然后重写onCreate函数构建界面,并添加事件侦听。这里我们适用java编码的方式构建界面,因为我们在新建项目时,就把gen这个目录已经剔除了。我的考虑可能是因为R中存储的都是资源的地址,在原生Android的应用中没有问题,但是AIR会重新编译和打包,所以在Android中的R里的地址可能在AIR中就变了,所以R也不能用。这只是一个猜的,具体还需要实验论证,等有时间了实验论证后再公布出来。

    1. package net.sswilliam.ane.callback;

    2. import android.app.Activity;
    3. import android.content.Intent;
    4. import android.os.Bundle;
    5. import android.view.View;
    6. import android.view.View.OnClickListener;
    7. import android.widget.Button;
    8. import android.widget.EditText;
    9. import android.widget.LinearLayout;

    10. public class MyActivity extends Activity implements OnClickListener{
    11.       //声明开启Activity的Action
    12.       public static final String MYACTIVITY_ACTION = "net.sswilliam.ane.callback.myactivity";
    13.      
    14.       private LinearLayout layout;
    15.       private EditText inputEdit;
    16.       private Button submit;
    17.       @Override
    18.       protected void onCreate(Bundle savedInstanceState) {
    19.             // TODO Auto-generated method stub
    20.             //构建界面
    21.             super.onCreate(savedInstanceState);
    22.             layout = new LinearLayout(this);
    23.             inputEdit = new EditText(this);
    24.             submit = new Button(this);
    25.             submit.setText("return");
    26.             layout.addView(inputEdit);
    27.             layout.addView(submit);
    28.             this.setContentView(layout);
    29.             //添加事件侦听
    30.             submit.setOnClickListener(this);
    31.       }
    32.       @Override
    33.       public void onClick(View v) {
    34.             // TODO Auto-generated method stub
    35.             //像预先注册过的BroadCastReceiver发送Intent以返回数据
    36.             Intent intent = new Intent(MyReceiver.MYARECEIVER_ACTION);
    37.            
    38.             intent.putExtra("data",this.inputEdit.getText().toString());
    39.             this.sendBroadcast(intent);
    40.             this.finish();
    41.            
    42.            
    43.       }

    44. }
    复制代码

    MyReceier

    MyReceiver是我们自定义的BroadCastReceiver,会被动态的注册到系统中从而侦听相应的Intent,首先我们定义需要侦听的IntentACTIONMYARECEIVER_ACTION = "net.sswilliam.ane.callback.myreceiver"。同时我们会传入CallBackContext的引用。这样可以在处理Intent时向Actionscript端抛出事件。

    注意FREContext中有一个dispatchStatusEventAsync方法可以从java代码向Actionscript端抛出ActionScript的事件。具体请查看NaiveExtension事件机制章节。

    1. package net.sswilliam.ane.callback;

    2. import com.adobe.fre.FREContext;

    3. import android.content.BroadcastReceiver;
    4. import android.content.Context;
    5. import android.content.Intent;

    6. public class MyReceiver extends BroadcastReceiver {
    7.       private FREContext context;
    8.       public static final String MYARECEIVER_ACTION = "net.sswilliam.ane.callback.myreceiver";
    9.       public MyReceiver(FREContext context){
    10.             this.context = context;
    11.       }

    12.       @Override
    13.       public void onReceive(Context arg0, Intent arg1) {
    14.             // TODO Auto-generated method stub
    15.             String data = arg1.getExtras().getString("data");
    16.             this.context.dispatchStatusEventAsync(CallBackContext.DATE_RECEIVE, data);

    17.       }

    18. }
    复制代码


    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    守望者AIR技术交流社区(www.airmyth.com)
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51753
    钢镚
    1422

    开源英雄守望者

     楼主| 发表于 2015-1-10 22:03:29 | 显示全部楼层
    Flex Library项目Flex Library项目目录和代码如下:


    CallBackExtension

    CallBackExtension是我们这个NativeExtensionActionscript的具体实现。同样我们会在其中先声明需要调用函数在Map中的Key,这两个KeyJava中的两个Key是完全相同的,申明成静态的常量可以减少编程时带来的拼写误差,也提高程序的可读性。


    1. public static const REGISTER_RECEIVER_FUNCTION:String = "register_receiver_function";
    2. public static const START_ACTIVITY_FUNCTION:String = "start_activity_function";
    复制代码

    对于Java端的两个函数,其中注册BroadCastReceiverRegisterReceiverFunction函数会在CallBackExtension新建时就调用。从而将我们自定义的BroadCastReceiver动态的注册进系统。而StartActivityFunction函数提供给第三方程序进行调用。

    1. public function CallBackExtension(target:IEventDispatcher=null)
    2. {
    3.                 super(target);
    4.                 ext = ExtensionContext.createExtensionContext("net.sswilliam.ane.callback","");
    5.                 ext.addEventListener(StatusEvent.STATUS,onDataReceived);
    6.                 ext.call(REGISTER_RECEIVER_FUNCTION);
    7. }
    8. public function startActivity():void{
    9.                 ext.call(START_ACTIVITY_FUNCTION);
    10. }
    复制代码

    同时需要给ExtensionContext添加事件侦听函数。从而获得从Java端抛出的Actionscript事件。具体请查看NaiveExtension事件机制章节。

    CallBackEvent

    CallBackEvent是自定义的一个事件类,将从Java端接收到的事件和数据封装为Actionscript的一个事件对象,供具体使用该NativeExtensionapp调用。

    1. package net.sswilliam.ane.callback
    2. {
    3.                 import flash.events.Event;
    4.                
    5.                 public class CallBackEvent extends Event
    6.                 {            
    7.                                 public static const DATE_RECEIVE:String = "data_receive";
    8.                               
    9.                                 public var callbackData:String = "";
    10.                                 public function CallBackEvent(callBackData:String, bubbles:Boolean=false, cancelable:Boolean=false)
    11.                                 {
    12.                                                 super(DATE_RECEIVE, bubbles, cancelable);
    13.                                                 this.callbackData = callBackData;
    14.                                 }
    15.                 }
    16. }
    复制代码

    extension.xml

    最后我们不能忘记在项目中添加相应的extension.xml文件对这个扩展做一个描述。大部分的tag都很清晰,就不过多解释了。注意的是namespace,虽然我们用3.0sdk,但是在NativeExtension中还是2.5

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <extension xmlns="http://ns.adobe.com/air/extension/2.5">
    3.   <id>net.sswilliam.ane.callback</id>
    4.   <versionNumber>1</versionNumber>
    5.   <platforms>
    6.     <platform name="Android-ARM">
    7.       <applicationDeployment>
    8.         <nativeLibrary>CallBack.jar</nativeLibrary>
    9.         <initializer>net.sswilliam.ane.callback.CallBackExtension</initializer>
    10.         <finalizer>net.sswilliam.ane.callback.CallBackExtension</finalizer>
    11.       </applicationDeployment>
    12.     </platform>
    13.   </platforms>
    14. </extension>
    复制代码

    Flex Mobile 项目

    Flex Mobile项目目录结构和代码如下:


    在这个项目中,重点不在于App的开发,而在于app.xml的配置。

    CallbackTest.mxml

    只是一个很简单调用我们NativeExtension的程序。我们会在程序启动时直接实例化NativeExtension,然后添加事件。并且通过一个Button来开启Java原生的Activity。最后显示从Java返回的数据。代码如下:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    3.                                                    xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="init(event)">
    4.                 <fx:Script>
    5.                                 <![CDATA[
    6.                                                 import mx.events.FlexEvent;
    7.                                                
    8.                                                 import net.sswilliam.ane.callback.CallBackEvent;
    9.                                                 import net.sswilliam.ane.callback.CallBackExtension;
    10.                                                
    11.                                                 import spark.effects.CallAction;
    12.                                                
    13.                                                 private var ext:CallBackExtension;
    14.                                                 protected function init(event:FlexEvent):void
    15.                                                 {
    16.                                                                 // TODO Auto-generated method stub
    17.                                                                 ext = new CallBackExtension();
    18.                                                                 ext.addEventListener(CallBackEvent.DATE_RECEIVE,dataReceiverHandler);
    19.                                                                
    20.                                                 }
    21.                                                 private function dataReceiverHandler(e:CallBackEvent):void{
    22.                                                                 this.console.appendText("data receiver:"+e.callbackData+"\n");
    23.                                                 }
    24.                                                
    25.                                                 protected function startActivity(event:MouseEvent):void
    26.                                                 {
    27.                                                                 // TODO Auto-generated method stub
    28.                                                                 this.ext.startActivity();
    29.                                                 }
    30.                                                
    31.                                 ]]>
    32.                 </fx:Script>
    33.                 <fx:Declarations>
    34.                                 <!-- 将非可视元素(例如服务、值对象)放在此处 -->
    35.                 </fx:Declarations>
    36.                 <s:Button x="10" y="10" label="call activity" click="startActivity(event)"/>
    37.                 <s:TextArea id="console" x="13" y="86" width="457" height="667"/>
    38. </s:Application>
    复制代码

    CallbackTest-app.xml

    每一个AIR程序都需要一个app.xml文件对其进行描述。当AIR支持Android平台后,在app.xml中就多了一个的tag。里面会有一个manifestAdditions的子tag。在这里,就可以包含针对Android程序中的AndroidManifest.xml的一些信息的添加和修改。默认的,在这个tag里会包含如下信息:

    1. <android>
    2.         <manifestAdditions><![CDATA[
    3.                                                 <manifest android:installLocation="auto">
    4.                                                                
    5.                                                     <!--See the Adobe AIR documentation for more information about setting Google Android permissions-->
    6.                                                     <!--删除 android.permission.INTERNET 权限将导致无法调试设备上的应用程序-->
    7.                                                     <uses-permission android:name="android.permission.INTERNET"/>
    8.                                                     <!--<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>-->
    9.                                                     <!--<uses-permission android:name="android.permission.READ_PHONE_STATE"/>-->
    10.                                                     <!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>-->
    11.                                                     <!--应同时切换 DISABLE_KEYGUARD 和 WAKE_LOCK 权限,才能访问 AIR
    12.                                 的 SystemIdleMode API-->
    13.                                                     <!--<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>-->
    14.                                                     <!--<uses-permission android:name="android.permission.WAKE_LOCK"/>-->
    15.                                                     <!--<uses-permission android:name="android.permission.CAMERA"/>-->
    16.                                                     <!--<uses-permission android:name="android.permission.RECORD_AUDIO"/>-->
    17.                                                     <!--应同时切换 ACCESS_NETWORK_STATE 和 ACCESS_WIFI_STATE 权限,才能使用 AIR
    18.                                 的 NetworkInfo API-->
    19.                                                     <!--<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>-->
    20.                                                     <!--<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>-->
    21.                                                 </manifest>
    22.                                                
    23.                                 ]]></manifestAdditions>
    24.     </android>
    复制代码

    从中可以看出,主要是对permission的一些设置。这些permissionAIR SDK自动添加到最终生成的AndroidManifest当中。

    在原生的Android App中,当我们需要注册一个Activity时,可以直接修改AndroidManifest.xml文件。那么当我们向要在用AIR开发的Android app注册一个Activity要怎么做呢?其实也很简单,只要在AIRapp.xmlAndroid中添加相应的Tag即可。如下图红色标记,这里我们就向我们的AIR app添加了一个MyActivityActivity。同时也定义了相应的IntentFilter。这里一定要注意两点

    1.       包括在application tag里,在原生Android开发中,Activity也是注册在application tag里的。但是AIRapp.xml里没有这个tag,经过测试,发现直接在app.xml里添加application tag,最终application tag里的内容也会合并到最后生成的AndroidManifest.xml中。

    2.       android:name的值与Android项目中的Activity的包路径相同。

    1. <android>
    2.         <manifestAdditions><![CDATA[
    3.                                                 <manifest android:installLocation="auto">
    4.                                                                 <application>
    5.                                                                                 <activity android:name="net.sswilliam.ane.callback.MyActivity">
    6.                                                                                 <intent-filter>
    7.                                                                                                 <action android:name="net.sswilliam.ane.callback.myactivity" />
    8.                                                                                                 <category android:name="android.intent.category.DEFAULT" />
    9.                                                                                                 </intent-filter>
    10.                                                                                 </activity>
    11.                                                 </application>
    12.                                                     <!--See the Adobe AIR documentation for more information about setting Google Android permissions-->
    13.                                                     <!--删除 android.permission.INTERNET 权限将导致无法调试设备上的应用程序-->
    14.                                                     <uses-permission android:name="android.permission.INTERNET"/>
    15.                                                     <!--<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>-->
    16.                                                     <!--<uses-permission android:name="android.permission.READ_PHONE_STATE"/>-->
    17.                                                     <!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>-->
    18.                                                     <!--应同时切换 DISABLE_KEYGUARD 和 WAKE_LOCK 权限,才能访问 AIR
    19.                                 的 SystemIdleMode API-->
    20.                                                     <!--<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>-->
    21.                                                     <!--<uses-permission android:name="android.permission.WAKE_LOCK"/>-->
    22.                                                     <!--<uses-permission android:name="android.permission.CAMERA"/>-->
    23.                                                     <!--<uses-permission android:name="android.permission.RECORD_AUDIO"/>-->
    24.                                                     <!--应同时切换 ACCESS_NETWORK_STATE 和 ACCESS_WIFI_STATE 权限,才能使用 AIR
    25.                                 的 NetworkInfo API-->
    26.                                                     <!--<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>-->
    27.                                                     <!--<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>-->
    28.                                                 </manifest>
    29.                                                
    30.                                 ]]></manifestAdditions>
    31.     </android>
    复制代码

    编译打包

    编译打包跟其他的NativeExtension没有什么区别,具体参见:http://sswilliam.blog.163.com/blog/static/1896963832011910111931102/

    http://sswilliam.blog.163.com/blog/static/1896963832011910111931102/


    再次重申一下,NativeExtension目前的开发还是挺麻烦的,大家一定要耐心+细心。做成功一遍后就基本不会遇到什么困难了。


    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    守望者AIR技术交流社区(www.airmyth.com)
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51753
    钢镚
    1422

    开源英雄守望者

     楼主| 发表于 2015-1-10 22:06:19 | 显示全部楼层
    NativeExtension的事件机制NativeExtension中通信方式主要由两种,一种是Actionscript直接通过call方法调用Native的代码,另外一种则是从Native代码像Actionscript抛出事件。这里主要讲解的是第二种方法。从Native代码向Actionscript抛出事件和Actionscript自身的事件机制非常相似。主要也是分为派发事件,侦听事件和处理事件三个部分。

    派发事件:

    派发事件主要是再Native code中执行,在Java中,就是调用FREContextdispatchStatusEventAsync(arg0, arg1),它和Actionscript中的dispatchEvent(event)是不同的。在Actionscript中的dispatchEvent方法中主要传入的参数是一个Event对象,这个Event的一些具体参数需要自己进行封装。而dispatchStatusEventAsync(arg0, arg1)传入的是两个String,这个方法会在java端像actionscript端抛出StatusEvent对象,arg0被当做StatusEventcodearg1被当做StatusEventlevel。其中level可以被用作事件传递的数据,如果有复杂格式的数据,可以将数据封装成json或者xml,或者就简单的用分隔符分隔开。

    Java端代码如下:

    1. this.context.dispatchStatusEventAsync("Status1", "data1;data2;data3");
    复制代码

    侦听事件:

    接收事件主要在Actionscript进行,直接在ExtensionContext对象上添加StatusEvent.Status事件的侦听即可

    1. ext = ExtensionContext.createExtensionContext("net.sswilliam.ane.callback","");
    2. ext.addEventListener(StatusEvent.STATUS,onDataReceived);
    复制代码

    处理事件:

    处理事件其实就是标准的用Switch Case处理StatusEvent事件的函数。官方文档里有很多范例。通过判断不同的codelevel从而进行具体的逻辑处理。

    1. private function onDataReceived(e:StatusEvent):void{
    2.                 switch(e.code)
    3.                 {
    4.                                 case  "Status1":
    5.                                 {
    6.                                                 var result:String  = e.level;
    7.                                                 var datas:Array = result.split(";");
    8.                                                 trace(datas);
    9.                                                 break;
    10.                                 }
    11.                                                                               
    12.                                 default:
    13.                                 {
    14.                                                 break;
    15.                                 }
    16.                 }
    17. }
    复制代码

    总结

    AIR开发的Android app中嵌入原生的Android的组件,其关键在于如何在app.xml中进行配置。因为AIR开发的Android app本质上还是一个Android app,必然需要一个AndroidManifest.xml。但是这个AndroidManifest.xml是由AIR自动生成的,我们只能在AIR app.xml中添加相应的参数变相的修改AndroidManifest.xml

    从这次试验的结果来看,AIR SDK会把app.xml中的

    1. <android>
    2.         <manifestAdditions><![CDATA[
    3.                                                
    4.                                 ]]></manifestAdditions>
    5.     </android>
    复制代码

    里的内容自动的映射到最终的AndroidManifest.xml中。

    如原本AIR APPAndroidManifest是这样的:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest android:versionCode="0" android:versionName="@string/app_version" android:installLocation="auto" package="air.CallbackTest.debug"
    3.   xmlns:android="http://schemas.android.com/apk/res/android">
    4.     <application android:label="@string/app_name" android:icon="@drawable/icon" android:hardwareAccelerated="true">
    5.         <activity android:theme="@style/Theme.NoShadow" android:label="@string/app_name" android:name=".AppEntry" android:launchMode="singleTask" android:screenOrientation="user" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="stateHidden|adjustResize">
    6.             <intent-filter>
    7.                 <action android:name="android.intent.action.MAIN" />
    8.                 <category android:name="android.intent.category.LAUNCHER" />
    9.             </intent-filter>
    10.             <meta-data android:name="autoOrients" android:value="false" />
    11.             <meta-data android:name="fullScreen" android:value="false" />
    12.             <meta-data android:name="uniqueappversionid" android:value="51f23dd3-5056-4831-ac9d-df2fcdca82a8" />
    13.             <meta-data android:name="initialcontent" android:value="CallbackTest.swf" />
    14.         </activity>
    15.     </application>
    16.     <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11" />
    17.     <uses-permission android:name="android.permission.INTERNET" />
    18. </manifest>
    复制代码

    如果我们在Android Tag中添加如下代码:

    1. <android>
    2.         <manifestAdditions><![CDATA[
    3.                                                 <manifest android:installLocation="auto">
    4.                                                                 <application>
    5.                                                                                 <activity android:name="net.sswilliam.ane.callback.MyActivity">
    6.                                                                                 <intent-filter>
    7.                                                                                                 <action android:name="net.sswilliam.ane.callback.myactivity" />
    8.                                                                                                 <category android:name="android.intent.category.DEFAULT" />
    9.                                                                                                 </intent-filter>
    10.                                                                                 </activity>
    11.                                                 </application>
    12.                                                
    13.                                                 </manifest>
    14.                                                
    15.                                 ]]></manifestAdditions>
    16.     </android>
    复制代码

    那么打包后再查看AndroidManifest.xml, 就会变成这样:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest android:versionCode="0" android:versionName="@string/app_version" android:installLocation="auto" package="air.CallbackTest.debug"
    3.   xmlns:android="http://schemas.android.com/apk/res/android">
    4.     <application android:label="@string/app_name" android:icon="@drawable/icon" android:hardwareAccelerated="true">
    5.         <activity android:theme="@style/Theme.NoShadow" android:label="@string/app_name" android:name=".AppEntry" android:launchMode="singleTask" android:screenOrientation="user"
    6. android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="stateHidden|adjustResize">
    7.             <intent-filter>
    8.                 <action android:name="android.intent.action.MAIN" />
    9.                 <category android:name="android.intent.category.LAUNCHER" />
    10.             </intent-filter>
    11.             <meta-data android:name="autoOrients" android:value="false" />
    12.             <meta-data android:name="fullScreen" android:value="false" />
    13.             <meta-data android:name="uniqueappversionid" android:value="ab57dfb0-5b52-4e80-8a6d-f9dedda9a76e" />
    14.             <meta-data android:name="initialcontent" android:value="CallbackTest.swf" />
    15.         </activity>
    16.         <activity android:name="net.sswilliam.ane.callback.MyActivity">
    17.             <intent-filter>
    18.                 <action android:name="net.sswilliam.ane.callback.myactivity" />
    19.                 <category android:name="android.intent.category.DEFAULT" />
    20.             </intent-filter>
    21.         </activity>
    22.     </application>
    23.     <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11" />
    24.     <uses-permission android:name="android.permission.INTERNET" />
    25. </manifest>
    复制代码

    Apktool是个很好的工具,大家不妨各种不同方法打包出来的apk文件反编译一下,就可以发现各自的实现原理了。


    守望者AIR技术交流社区(www.airmyth.com)
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2019-10-19 14:43 , Processed in 0.052724 second(s), 33 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表