Nativescript: [NS7] - Android error extending custom activity

Created on 24 Sep 2020  路  14Comments  路  Source: NativeScript/NativeScript

Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: 7.0.8
  • Cross-platform modules: 7.0.0
  • Android Runtime: 7.0.0
  • iOS Runtime: 7.0.0
  • Plugin(s):

Describe the bug
I've a custom application in AndroidManifest.xml, I've followed this guide but it doesn't work:
https://docs.nativescript.org/core-concepts/android-runtime/advanced-topics/extend-application-activity

If I run application I've this error:

09-24 16:58:29.251 11882 11882 E AndroidRuntime: java.lang.RuntimeException: Unable to instantiate application com.custom.NativeScriptApplication: java.lang.ClassNotFoundException: Didn't find class "com.custom.NativeScriptApplication" on path: DexPathList[[zip file "/data/app/org.nativescript.testnsng-n9D3x_-2ywiadEyA-gCknQ==/base.apk"],nativeLibraryDirectories=[/data/app/org.nativescript.testnsng-n9D3x_-2ywiadEyA-gCknQ==/lib/x86_64, /data/app/org.nativescript.testnsng-n9D3x_-2ywiadEyA-gCknQ==/base.apk!/lib/x86_64, /system/lib64]]

To Reproduce
I've added a custom application: com.custom.NativeScriptApplication
It' defined in application.android.ts, if I leave com.tns.NativeScriptApplication everything works fine.

Sample project
https://github.com/mapo80/nativescript-ns7-custom-application

Most helpful comment

@mapo80 in your webpack.custom.config.js you are setting

    env.appComponents = env.appComponents || [];
    env.entries = env.entries || {};

But these are not read from env in the main config:

  // Add your custom Activities, Services and other Android app components here.
  const appComponents = [
    "@nativescript/core/ui/frame", "@nativescript/core/ui/frame/activity"
  ];

  // ...

  const entries = { bundle: entryPath };

Adding the entry and appComponents to the main config works fine as @bradmartin has tried.

Perhaps we could allow passing these through env - it should be a fairly simple change if you don't mind opening a pr: https://github.com/NativeScript/NativeScript/tree/master/packages/webpack/templates these are the default templates - that could just use something like this:

{
  // ...
  appComponents = [],
  entries = {}
} = env;

appComponents = appComponents.concat( [
    "@nativescript/core/ui/frame", "@nativescript/core/ui/frame/activity"
]);

entries = Object.assign({ bundle: entryPath }, entries); // this way allows changing `bundle` entry too

All 14 comments

Hi, we are experiencing a similiar issue. We also followed this guide to add a custom android activity.
However it does not seem to work like this with NS7

activity.android.ts (Changed the decorator to @NativeClass())

@NativeClass()
class MainActivity extends androidx.appcompat.app.AppCompatActivity {
...

AndroidManifest.xml

android:name="org.test.nativescript.MainActivity"

webpack.config.js

// Add your custom Activities, Services and other Android app components here.
    const appComponents = [
        "@nativescript/core/ui/frame", "@nativescript/core/ui/frame/activity", resolve(__dirname, "app/activity.android.ts")
    ];
...
System.err: java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{org.test.devel/org.test.nativescript.MainActivity}: java.lang.ClassNotFoundException: Didn't find class "org.test.nativescript.MainActivity" on path: DexPathList[[zip file "/data/app/org.test.devel-E-QBEl2fMKc8Rcn-r1WvXQ==/base.apk"],nativeLibraryDirectories=[/data/app/org.test.devel-E-QBEl2fMKc8Rcn-r1WvXQ==/lib/x86, /data/app/org.test.devel-E-QBEl2fMKc8Rcn-r1WvXQ==/base.apk!/lib/x86, /system/lib]]
System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2843)
System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
System.err:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
System.err:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
System.err:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
System.err:     at android.os.Looper.loop(Looper.java:193)
System.err:     at android.app.ActivityThread.main(ActivityThread.java:6669)
System.err:     at java.lang.reflect.Method.invoke(Native Method)
System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
System.err: Caused by: java.lang.ClassNotFoundException: Didn't find class "org.test.nativescript.MainActivity" on path: DexPathList[[zip file "/data/app/org.test.devel-E-QBEl2fMKc8Rcn-r1WvXQ==/base.apk"],nativeLibraryDirectories=[/data/app/org.test.devel-E-QBEl2fMKc8Rcn-r1WvXQ==/lib/x86, /data/app/org.test.devel-E-QBEl2fMKc8Rcn-r1WvXQ==/base.apk!/lib/x86, /system/lib]]
System.err:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
System.err:     at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
System.err:     at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
System.err:     at android.app.Instrumentation.newActivity(Instrumentation.java:1215)
System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2831)
System.err:     ... 11 more

Hey @mapo80 and @shansb-dev can you remove the .ts from the activity in the webpack.config you have. I believe that might be part of the issue.

extended activity

import {
  AndroidActivityCallbacks,
  setActivityCallbacks
} from '@nativescript/core';
import * as application from '@nativescript/core/application';


@NativeClass()
@JavaProxy('com.permobil.smartdrive.wearos.MainActivity')
@Interfaces([androidx.wear.ambient.AmbientModeSupport.AmbientCallbackProvider])
class MainActivity
  extends androidx.appcompat.app.AppCompatActivity
  implements androidx.wear.ambient.AmbientModeSupport.AmbientCallbackProvider {
  constructor() {
    super();
  }

webpack.config.js

 appComponents.push(
    ...['@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity'],
    resolve(__dirname, 'app/main-activity')
)

Android Manifest

       <!-- for main activity -->
        <activity
            android:name="com.permobil.smartdrive.wearos.MainActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:label="@string/title_activity_kimera"
            android:launchMode="singleInstance"
            android:theme="@style/LaunchScreenTheme">
            <meta-data

I have this working with 2 different NS7 android apps.

Let me know if this is helpful or not.

@mapo80 you repo in your link doesn't have the activity in the webpack.config here: https://github.com/mapo80/nativescript-ns7-custom-application/blob/72b7c4afe8092f5ab9264196ef6347f0df1b6eca/webpack.config.js#L30 so I'd add it as I mentioned in my previous comment and see if that helps, I don't use the file extension on the files as that has always caused me issues with webpack going back over a year ago.

Sorry @bradmartin bu the example you posted is for Activity and not for Application.
As writen here:

https://docs.nativescript.org/core-concepts/android-runtime/advanced-topics/extend-application-activity

appComponents is for Activities and application entry is for android.app.Application.
Your suggestion doesn't solve the issue.

Moreover It's not good to change default webpack configuration because it could be overwritten.

You sometimes have to change the webpack.config :) depending on what you're trying to do, I do see you're extending it which is a better practice tho 馃憤. I do see now you're doing the application and not activity.

@bradmartin thanks for your quick reply, that did the trick ;)

@bradmartin ok, thanks but it doesn't work for Application.

Got it working with your sample, will push it to my fork and PR to you so you can review. It might be that extended webpack config causing issues so we may have to adjust the CLI for this. Not certain,need to review the actual changes I made.

@mapo80 - https://github.com/mapo80/nativescript-ns7-custom-application/pull/1 which basically just added the application file to the main webpack.config, I'm guessing the custom config might not be finding the correct entry point. I noticed during the webpack process after first pulling a warning is printed that the file is included but it's not being used. Which makes me think how you have the custom config setup to find that file is incorrect somehow.

@mapo80 in your webpack.custom.config.js you are setting

    env.appComponents = env.appComponents || [];
    env.entries = env.entries || {};

But these are not read from env in the main config:

  // Add your custom Activities, Services and other Android app components here.
  const appComponents = [
    "@nativescript/core/ui/frame", "@nativescript/core/ui/frame/activity"
  ];

  // ...

  const entries = { bundle: entryPath };

Adding the entry and appComponents to the main config works fine as @bradmartin has tried.

Perhaps we could allow passing these through env - it should be a fairly simple change if you don't mind opening a pr: https://github.com/NativeScript/NativeScript/tree/master/packages/webpack/templates these are the default templates - that could just use something like this:

{
  // ...
  appComponents = [],
  entries = {}
} = env;

appComponents = appComponents.concat( [
    "@nativescript/core/ui/frame", "@nativescript/core/ui/frame/activity"
]);

entries = Object.assign({ bundle: entryPath }, entries); // this way allows changing `bundle` entry too

Hi @bradmartin, I've test your PR and now it works.
I noticed that during build there was a warning on that file. I don't like to change directly webpack.config.js but I'll use it as temporary fix even if I have to make many changes to my custom webpack config.

thanks @bradmartin

@rigor789 I'll try to make a PR for webpack.angular.js

Thanks for your advice.

Hi @rigor789, I've created PR to fix this issue. Let me know if it is ok.

I have a similar problem and have not opened a new ticket.

I am using the nativescript@next version from NS.
I spent the last hours trying to use Activity in my test app.

I follow the instructions on the page:
https://docs.nativescript.org/angular/core-concepts/android-runtime/advanced-topics/extend-application-activity

The following system error occurred while following the instructions:
Error: com.tns.system.classes.loading.LookedUpClassNotFound: Class "org.myApp.MainActivity" not found.

After several hours of testing, I was able to make my app work and came to the following conclusions:

  1. activity.android.js must exist even when working with activity.android.ts otherwise no file is generated: MainActivity.java
  2. activity.android.js - should contain a declaration for all methods
  3. set webpack.config.js, AndroidManifest.xml according to the instructions on the page
    I use the .ts extension: resolve (__ dirname, "app / activity.android.ts"),
  4. be sure to run: ns build android, check if the MainActivity.java file has been generated
  5. now: ns run android ... the application now does not report an error and seems to me that uses the method code from activity.android.ts

The order of ns build and later ns run / debug is very important, it must be started this way, otherwise there is no error:

With the little knowledge I have on this topic, it seems to me that activity.android.js must have all JS methods declared, and in this way somehow take the method code from the activity.android.ts file.

If the method is not declared in .js it will not work in .ts

Currently the best solution is to use only the activity.android.js version until the bug is resolved.

Maybe what I wrote will help you solve this bug with activity.android.ts in the application.

Best regards,
Dean

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nirsalon picture nirsalon  路  3Comments

minjunlan picture minjunlan  路  3Comments

dhanalakshmitawwa picture dhanalakshmitawwa  路  3Comments

NordlingDev picture NordlingDev  路  3Comments

Pourya8366 picture Pourya8366  路  3Comments