Question

I'm currently working on creating an Android ANE for native alert popups. I'm now at the point where I think my both my Java and AS3 code is good to go but I'm getting an error when I try to use it.

Main Thread (Suspended: TypeError: Error #1009: Cannot access a property or method of a null object reference.)

My problem is I'm really not sure where this error is coming from. My thinking is that I'm not building the ANE file correctly or something is wrong in my extension.xml file but I'm really not too sure.

I'm going to try to provide as much information as I can about how this project is set up. Right now I'm trying to use this ANE in a small, testing application.

First, the folder setup:

ANEextensions-

     Alert_Java (holding my Java project)

          (Android/Java created assets. Not sure if these are important or now. If so I will list them)

          src

               com

                    fa

                         ne                        

                              android

                                   AlertContext.java

                                   AlertExtension.java

                                   ShowAlert.java

     Alert_AS

          bin

               AlertAndroidAS.swc

          src

               Alert.as

               extension.xml

I'm not going to bother posting my java code as I think it's correct. but if anyone who is willing to invest some time in helping me with this issue wants to take a look please let me know.

This is my extensions.xml file

<extension xmlns="http://ns.adobe.com/air/extension/2.5">

<id>com.fa.alerts</id>

<versionNumber>1.0</versionNumber>

    <platforms>

        <platform name="Android-ARM">

            <applicationDeployment>

                <nativeLibrary>AndroidAlert.jar</nativeLibrary>

                <initializer>com.fa.ne.android.AlertExtension</initializer>

                <finalizer>com.fa.ne.android.AlertExtension</finalizer>

            </applicationDeployment>

        </platform>

    </platforms>

</extension>

And this is my Alert.as file:

package {

    import flash.events.EventDispatcher;

    import flash.external.ExtensionContext;



    public class Alert extends EventDispatcher{

        public static var extContext:ExtensionContext = null

        public function Alert(){

            super();



            extContext = ExtensionContext.createExtensionContext("com.fa.alerts", null);



        }



        public static function androidAlert(aTitle:String, aMsg:String, aNeg:String = "Cancel", aPos:String = "Ok"):void{

            extContext.call("showAlert", aTitle, aMsg, aNeg, aPos);

        }

    }

}

And this is my stub app I'm using to test

<?xml version="1.0" encoding="utf-8"?>

<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 

        xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">



    <fx:Script>

        <![CDATA[



            protected function spawnAne(event:MouseEvent):void{



                var a:Alert = new Alert();

                Alert.androidAlert("test","testing");

            }

        ]]>

    </fx:Script>



    <fx:Declarations>

        <!-- Place non-visual elements (e.g., services, value objects) here -->

    </fx:Declarations>

    <s:Button click="spawnAne(event)" />

</s:View>

Now clicking on that button is what causes the error.

I don't have any kind of swc or link between my testing app and the AS3 Alert_AS project. I'm using Flash Builder 4.6 to import the ANE file using the IDE tools.

To build my ANE I'm using a lightly modified bash script from this post: http://gotoandlearn.com/play.php?id=149 by Lee Brimelow

# path to YOUR Android SDK
export AIR_ANDROID_SDK_HOME="my sdk"

# path to the ADT tool in Flash Builder sdks
ADT="my adt"

# native project folder
NATIVE_FOLDER=Alert_Java

# AS lib folder
LIB_FOLDER=Alert_AS

# name of ANE file
ANE_NAME=AndroidAlert.ane

# JAR filename
JAR_NAME=AndroidAlert.jar


# cert path
CERT_NAME=cert.p12

# cert password
CERT_PASS=password

#===================================================================

echo "****** preparing ANE package sources *******"

rm ${ANE_NAME}
rm -rf ./build/ane
mkdir -p ./build/ane
mkdir -p ./build/ane/Android-ARM
mkdir -p ./build/ane/Android-ARM/res

# copy resources
cp -R ./${NATIVE_FOLDER}/res/* ./build/ane/Android-ARM/res

# create the JAR file
jar cf ./build/ane/Android-ARM/${JAR_NAME} -C ./${NATIVE_FOLDER}/bin .

# grab the extension descriptor and SWC library 
cp ./${LIB_FOLDER}/src/extension.xml ./build/ane/
cp ./${LIB_FOLDER}/bin/*.swc ./build/ane/
unzip ./build/ane/*.swc -d ./build/ane
mv ./build/ane/library.swf ./build/ane/Android-ARM


echo "****** creating ANE package *******"

"$ADT" -package -storetype PKCS12 -keystore ./cert.p12 -storepass password -tsa none \
    -target ane \
    ${ANE_NAME} \
    ./build/ane/extension.xml \
    -swc ./build/ane/*.swc \
    -platform Android-ARM \
    -C ./build/ane/Android-ARM/ .

echo "****** ANE package created *******"

I know this is a bit long but any help would be greatly appreciated! And feel free to let me know if you need some more elaboration

Added Java code

I modified the original code a bit. I removed AlertExtension.java and moved the get context function to AlertContext.java. I was thinking this would solve my issue but I'm still getting the same result. Here is my code:

AlertContext.java, I'm assuming the createContext method is fired after var a:Alert = new Alert();

package com.fa.ne.android;

import java.util.Map;
import java.util.HashMap;

import com.adobe.fre.FREContext;
import com.adobe.fre.FREExtension;
import com.adobe.fre.FREFunction;

public class AlertContext extends FREContext implements FREExtension {

@Override
public FREContext createContext(String type){
    return new AlertContext();
}

@Override
public void initialize(){

}
@Override
public void dispose() {

}

@Override
public Map<String, FREFunction> getFunctions() {

    HashMap<String, FREFunction> functionMap = new HashMap<String, FREFunction>(); 
    functionMap.put("showAlert", new ShowAlert());
    return functionMap;
}




}

Here is my ShowAlert class

package com.fa.ne.android;

import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;

import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREInvalidObjectException;
import com.adobe.fre.FREObject;
import com.adobe.fre.FRETypeMismatchException;
import com.adobe.fre.FREWrongThreadException;


public class ShowAlert implements FREFunction {

@Override
public FREObject call(FREContext aContext, FREObject[] aPassedArgs) {
    //get activity
    Activity a = aContext.getActivity();
    //grabbing context
    final FREContext context = aContext; 
    try{
        //getting the title and msg for alert as string
        String title = aPassedArgs[0].getAsString();
        String message = aPassedArgs[1].getAsString();
        String negitive = aPassedArgs[3].getAsString();
        String positive = aPassedArgs[4].getAsString();
        //creating the alert builder with the activity
        Builder builder = new Builder(a);
        //setting the title and msg
        builder.setTitle(title);
        builder.setMessage(message);
        //setting up buttons, negative and positive, each with an event so we can listen in AS3
        //doing listeners inline
        builder.setNegativeButton(negitive, new OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int dig){
                context.dispatchStatusEventAsync("nativeAlert", "negitive");
            }

        }).setNeutralButton(positive, new OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int dig){
                context.dispatchStatusEventAsync("positiveAlert", "positive");
            }
        });
        //done building, time to alert and return
        builder.create().show();

        return FREObject.newObject(true);

        //error handeling
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (FRETypeMismatchException e) {
        e.printStackTrace();
    } catch (FREInvalidObjectException e) {
        e.printStackTrace();
    } catch (FREWrongThreadException e) {
        e.printStackTrace();
    }

    return null;
}

}
Was it helpful?

Solution

Quick tip, create a function, which tells you whether the extension is available.

public static function isSupported():Boolean
{
     return extContext != null;
}

Hope this helps.

Also it's good to add a default implementation of the native extension, which can bee ritten entierly in actions script and will be used when you run the app in emulator.

For more information look here:

http://www.adobe.com/devnet/air/articles/extending-air.html

OTHER TIPS

I can't really answer your question. I don't know Java (it reads like pseudo ActionScript for me heehhehee). However, this might offer you some help & someone you could refer back here who might spot the problem easily.

Piotr Walczyszyn created an Android native alert / push extension here: http://www.riaspace.com/2011/09/as3c2dm-air-native-extension-to-push-notifications-with-c2dm/

In the comments I also found another person with an extensive tutorial for native alerts in iOS here: http://www.liquid-photo.com/2011/10/28/native-extension-for-adobe-air-and-ios-101/

I was reading the comments on Piotr's post and some things he said leads me to wonder if this line

extContext = ExtensionContext.createExtensionContext("com.fa.alerts", null);

might be causing/related to the problem

Hope this can help you and/or others.

Best of luck everyone!

Todd

...back to researching push notification options/viability =D

I kept running into your problem too.

The ONLY tutorial I have been able to get to work (with some changes) has been the one found here.

http://www.adobe.com/devnet/air/articles/developing-native-extensions-air.html

I had to add -swf-version 13 to the flex library compiler.

And I had to add -tsa none to the adt command to build the ANE file.

Did You link the extension to the Android platform in FlashBuilder? Just adding it to the NativeExtension tab in "Flex Build Path" is not enough You also have to check the checkbox in

"Flex Build Packaging" >> "Google Andorid">> "Native Extension"

Also You can try to look at the diference and maby somthing will help from my porject: NativeAlert

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top