Sub Process Global variables

walterf25

Expert
Licensed User
Longtime User
Hello everyone, i was wondering if anyone could answer this question, why is it that when you create a library and port it to Basic4Android, sometimes you can not declare a variable to use that specific library under the Sub Process Global subroutine, I have created a library for an Airpush Ad company and i can not use this library in a service because i can not declare the variable under Sub Process Global routine.
Does anyone have any ideas, or knows of a way to go around this issue, I apologize beforehand if the question seems stupid, but i need to find a fix for this.

Here's the scenario, when the user installs my app, there will be a push notification ad sent for the first time, the push notifications are scheduled on the server side to be pushed twice per day, but if the user re-boots the phone there needs to be a check to see if the phone has been re-booted and have the notifications re-initialized, otherwise the user will not receive any further push notification ads.

any ideas anyone?

Thanks,
Walter
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
If you declare your object as an @ActivityObject then you cannot declare it as a process global variable. The reason is that this object holds a reference to the activity. Holding a reference to this object from process_globals will result in a memory leak.
If you remove this annotation the BA object you receive will not have an activity context. If this object wraps a view then it will not work.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Are you speaking chineese?

Hi Erel, i'm sorry but i'm a little lost, here's how i have declared my code in Eclipse

B4X:
public class SendDroidAds extends SendDroid{
   String APP_ID = "";
   public void Initialize(BA ba, String APP_ID, Boolean testmode){
      new SendDroid(ba.activity, APP_ID, ba.context.getPackageName(), testmode.booleanValue());
       Log.v("Nick", "PublihserId" + APP_ID);
          Log.v("Nick", "PackageName " + ba.context.getPackageName());
         this.APP_ID = APP_ID;
   }

can you show me how to do it so that i can use this when i declare the variable in Sub Process globals please?

thanks Erel,
Walter
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Another problem

Hi there, thanks for that tip, i have removed the @ActivityObject annotation, but now the library will not work
it gives me this error now!

** Service (bootreceiver) Start **
bootreceiver_service_start (java line: 104)

java.lang.NullPointerException
at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:353)
at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:348)
at com.senddroid.SendDroid.<init>(SendDroid.java:165)
at com.senddroid.SendDroid.<init>(SendDroid.java:105)
at com.dandre.sendroid.ads.SendDroidNotifications.Initialize(SendDroidNotifications.java:39)
at com.dandre.lake.bootreceiver._service_start(bootreceiver.java:104)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:154)
at com.dandre.lake.bootreceiver.handleStart(bootreceiver.java:61)
at com.dandre.lake.bootreceiver.onStartCommand(bootreceiver.java:46)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2115)


at android.app.ActivityThread.access$2800(ActivityThread.java:124)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1031)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3806)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: Unable to start service com.dandre.lake.bootreceiver@4054b5f0 with Intent { cmp=com.dandre.lake/.bootreceiver (has extras) }: java.lang.RuntimeException: java.lang.NullPointerException


at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2128)
at android.app.ActivityThread.access$2800(ActivityThread.java:124)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1031)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3806)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:199)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:154)
at com.dandre.lake.bootreceiver.handleStart(bootreceiver.java:61)
at com.dandre.lake.bootreceiver.onStartCommand(bootreceiver.java:46)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2115)
... 10 more
Caused by: java.lang.NullPointerException
at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:353)
at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:348)
at com.senddroid.SendDroid.<init>(SendDroid.java:165)
at com.senddroid.SendDroid.<init>(SendDroid.java:105)
at com.dandre.sendroid.ads.SendDroidNotifications.Initialize(SendDroidNotifications.java:39)
at com.dandre.lake.bootreceiver._service_start(bootreceiver.java:104)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:170)
... 14 more

any ideas as to why this is?

thanks again!
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
There are two type of BA object - an Activity BA and a Process BA.

If your library has the annotation @ActivityObject then all methods in your library are passed an Activity BA.

If that annotation is not present then all methods in the library are passed a Process BA.

Your library is trying to use SharedPreferences and requires a reference to the Activity Context, you were probably previously doing something like this:

B4X:
public void MyMethod(BA pBA){
  SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(pBA.context);
  // more code here
}

PreferenceManager | Android Developers

The parameter pBA is an Activity BA as you had included the annotation @ActivityObject and it all works.
Next you removed that annotation and the parameter pBA is now a Process BA object - pBA.context is probably null, a Process BA object has no reference to an Activity context.

I'm not sure what the solution is - hopefully Erel will help there!

Martin.
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Thanks

Thanks for that exaplanation warwound, thing are a little more clear now, Erel, do you have any suggestions on how to fix this?

I have removed the @ActivityObject annotation and this is how my code looks

B4X:
public class SendDroidAds extends SendDroid{
   String APP_ID = "";
   public void Initialize(BA ba, String APP_ID, Boolean testmode){
      new SendDroid(ba.activity, APP_ID, ba.context.getPackageName(), testmode.booleanValue());
       Log.v("Nick", "PublihserId" + APP_ID);
          Log.v("Nick", "PackageName " + ba.context.getPackageName());
         this.APP_ID = APP_ID;
   }

but i still get the error mentioned in the previous post, help Erel, I would like to be able to use this library in both an activity and in a service module.

thanks,
Walter
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Sub Process Global

Ok, I understand that much, my question is if i want to declare the variable of this library under the Sub Process Global of a service module, and not have it B4Android complaint when i try to run it, what should I do, i'm sorry if i'm not being clear, i just need to figure out what changes to make to make this work, I have already removed the @ActivityObject annotation, so in order for this to work, how should I code the library so i can call this from a service module.

B4X:
public class SendDroidAds extends SendDroid{
    String APP_ID = "";
    public void Initialize(BA ba, String APP_ID, Boolean testmode){
        new SendDroid(ba.activity, APP_ID, ba.context.getPackageName(), testmode.booleanValue());
         Log.v("Nick", "PublihserId" + APP_ID);
            Log.v("Nick", "PackageName " + ba.context.getPackageName());
           this.APP_ID = APP_ID;
    }
since i have removed @ActivityObject, then ba will return null, so if i want it to work, how should i code this?

thanks Erel
Sorry for any confusion!
 
Upvote 0

walterf25

Expert
Licensed User
Longtime User
Sub Process Global

SendDroid is a push notification Ad, initially it requires you to start like this

B4X:
public class SendDroidAds extends SendDroid{
    String APP_ID = "";
    public void Initialize(BA ba, String APP_ID, Boolean afterreboot){       'this parameter requires to be false when you first initialize the variable, and if the user reboots the phone, then you need to call this again but with the afterreboot variable set to true, this way the sdk knows to automatically send a new push notification ad right away after phone has been rebooted, but this time this need to be called from a service module.
        new SendDroid(ba.activity, APP_ID, ba.context.getPackageName(), testmode.booleanValue());
         Log.v("Nick", "PublihserId" + APP_ID);
            Log.v("Nick", "PackageName " + ba.context.getPackageName());
           this.APP_ID = APP_ID;
    }

here's the code needed on the bootreceiver class

B4X:
public class BootReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
new SendDroid(context, “APP_ID”, context.getPackageName(), true);
}
}

thanks for your help Erel!
 
Upvote 0
Top