Java Question Start Activity From Library

XverhelstX

Well-Known Member
Licensed User
Longtime User
Hey,

I'm wondering if it is possible to start an Activity in my B4A code from a library.

Something like:
Java:
B4X:
@ShortName("LibActivity")
public class myActivityWrapper extends ThisActivity{

}

Where ThisActivity is an Activity from a jar file.

b4a
B4X:
dim myActivityFromTheLibrary as LibActivity
StartActivity(myActivityFromTheLIbrary)

Thanks,
Tomas

EDIT: The title may sound other then what i mean.

I mean I want to call an Activity from my Basic4Android code that launches an activity from the library
 
Last edited:

XverhelstX

Well-Known Member
Licensed User
Longtime User
i'm getting the following error:

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.rootsoft.test/org.dev.test.ui.activity.Activity}: java.lang.InstantiationException: can't instantiate class org.dev.test.ui.activity.Activity


at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1880)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.InstantiationException: can't instantiate class org.dev.test.ui.activity.Activity
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1319)
at android.app.Instrumentation.newActivity(Instrumentation.java:1023)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1871)
... 11 more

B4X:
public Intent CreateIntent(BA pBA){
        Intent intent1 = new Intent(pBA.context, Activity.class);
        return intent1;
    }

B4X:
StartActivity(myActivityFromTheLibrary.CreateIntent)

B4X:
AddApplicationText(<activity android:name="org.dev.test.ui.activity.Activity" />)

Note that it's not actually called like Activity. it has another name which i won't share yet for a new lib i'm trying to make.
Tomas
 
Last edited:

warwound

Expert
Licensed User
Longtime User
If your library contains one or more complete Activities then you first need to add them to your B4A project in the manifest:

B4X:
'End of default text.
AddApplicationText(<activity android:name="com.mypackagename.MyActivityName" />)

Now you need an Intent to start that Activity - i never successfuly got a B4A Intent to open an Activity contained in a library so used the java Intent instead.

You can create a method in your library that returns the desired Intent and then use that Intent in B4A with StartActivity:

Library method:

B4X:
public class Helper {
   public static Intent GetMyIntent(BA pBA){
      return new Intent(pBA.activity, MyActivityName.class);
   }
}

B4A code:

B4X:
Dim Helper1 As Helper
StartActivity(Helper1.GetMyIntent)

You might find this thread interesting: http://www.b4x.com/forum/libraries-developers-questions/18730-start-library-activity.html

Martin.
 

XverhelstX

Well-Known Member
Licensed User
Longtime User

warwound

Expert
Licensed User
Longtime User
Tomas wants to create an Activity in his library extends another 3rd party Activity.

Much like i wanted to create an Activity which extended MapActivity.

I think he will face the same problems - trying to get B4A to compile a project that contains an unsupported Activity.

Martin.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
There should not be a problem to create activities inside the library. This is done in several libraries such as PreferenceActivity and some of the ads libraries.

The problem with such solutions is that it is difficult to communicate with this activity.

About the logs, I think that the you didn't post the section with the real cause for this error.
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
Warwound and I looked at this further and apparently it seems that the engine extends another class.

For example, it looks like this:

B4X:
public void AndEngine extends AndActivity {

}

This way it is not possible for us to extend the Activity without writing an "AndActivityWrapper".

I'm wondering if there's a way to do this?

Tomas
 

warwound

Expert
Licensed User
Longtime User
It seems to me as though B4A can compile activities which are 'standard' Android Activity classes and also activities that are sub-classes of the standard Android Activity BUT only if that sub-class of the Android Activity is part of the Android SDK.

PreferenceActivity and ListActivity compile with no problems for example.

My attempts to add a MapActivity to a B4A project failed because MapActivity is not part of the standard Android SDK, it's part of the google add-ons packages.
I could not get B4A to use the add on package when compiling.

And i think this is where Tomas will have a similar problem - the sub-classed Activity he wants to compile is not part of the Android SDK.

Is it because the B4A ActivityWrapper only works with Activity classes that are part of the SDK?

Or is it just that Tomas and myself don't know enough about Android and how the B4A complier works...?

Martin.
 

warwound

Expert
Licensed User
Longtime User
Well i don't have the time to spare to repeat my MapView a non-starter? findings.

I have today created a B4A library with two classes:

B4X:
package uk.co.martinpearman.b4a.googlemapview;

import android.os.Bundle;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.Hide;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

@DependsOn(values = { "maps" })
@Hide
public class MyMapView extends MapActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        MapView mapView = new MapView(this, "0k1SIJwKfCiZzLeQxv6UEHoTeHXJzmX7uYlDXUg");
        setContentView(mapView);   
    }
   @Override
   protected boolean isRouteDisplayed() {
      return false;
   }
}

B4X:
package uk.co.martinpearman.b4a.googlemapview;

import android.content.Intent;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.Author;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;

@ActivityObject
@Author("Martin Pearman")
@Permissions(values = { "android.permission.INTERNET" })
@ShortName("IntentCreator")
@Version(1.0f)
public class IntentCreator {
   public Intent GetIntent(BA pBA){
      return new Intent(pBA.activity, MyMapView.class);
   }
}

A MapActivity and a lib to create an Intent to start that MapActivity.

The Google API v8 is used to compile the library and Google API v8 add on maps.jar is in my B4A additional libraries folder and also on the Eclipse buildpath.

The library compiles with no problems and a sample B4A project is:

B4X:
Sub Process_Globals
End Sub

Sub Globals
   Dim Test As IntentCreator
End Sub

Sub Activity_Create(FirstTime As Boolean)
   StartActivity(Test.GetIntent)
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

A manifest edit:

'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: Manifest Editor
AddManifestText(
<uses-sdk android:minSdkVersion="8" />
<supports-screens android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.
AddManifestText(<uses-library android:name="com.google.android.maps" />)
AddApplicationText(<activity android:name="uk.co.martinpearman.b4a.googlemapview.MyMapView" />)

And a typical force close:

** Activity (main) Create, isFirst = true **


main_activity_create (java line: 209)


java.lang.NoClassDefFoundError: uk.co.martinpearman.b4a.googlemapview.MyMapView


at uk.co.martinpearman.b4a.googlemapview.IntentCreator.GetIntent(IntentCreator.java:18)
at com.deleteme.b4a.mymapviewdemo.main._activity_create(main.java:209)
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 com.deleteme.b4a.mymapviewdemo.main.afterFirstLayout(main.java:84)
at com.deleteme.b4a.mymapviewdemo.main.access$100(main.java:16)
at com.deleteme.b4a.mymapviewdemo.main$WaitForLayout.run(main.java:72)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3835)
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:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

Dex2jar shows that the APK compiled by B4A contains both library classes BUT no matter what i try the MapActivity never works.

I'm not gonna spend time trying yet again to get a MapActivity to compile into a B4A project but have posted this just to show that using a sub-class of Activity that is not part of the native SDK seems to be problematic (read impossible)...

Martin.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
SS-2012-08-02_11.46.48.png


The issue here is different. It is related to maps being a system library.

I did two things two compile it:
1. It should be AddApplicationText instead of AddManifestText (for the use-library).
2. Remove the DependsOn annotation. The classes are already available in the device.
 

warwound

Expert
Licensed User
Longtime User
:sign0060:

It works!
And if i'd got the MapView API key correct it would even have displayed tiles.

Now this doesn't mean that the a Google MapView can be wrapped as OSMDroid is - a Google Map can now be a (pre-compiled) MapActivity that can be added to a B4A project but NOT a View that can be added to a B4A Activity.

Anyway let's see how Tomas gets on with his Activity sub-classes...

Martin.
 

warwound

Expert
Licensed User
Longtime User
Hi.

I doubt you'll find the code useful but i have re-uploaded it for you to take a look at.

The library is simply a java android MapActivity:

B4X:
public class MyMapView extends MapActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        MapView mapView = new MapView(this, "api_key_here");
        mapView.setBuiltInZoomControls(true);
        mapView.setClickable(true);
        setContentView(mapView);   
    }
   @Override
   protected boolean isRouteDisplayed() {
      return false;
   }
}

The B4A code does nothing more than start that activity with an Intent.

http://android.martinpearman.co.uk/b4a/temp/GoogleMapViewActivity.zip

Martin.
 
Top