10

I have some problems with my Native Activity application. It works fine on 99% of devices. But sometimes users get the following error:

java.lang.RuntimeException: Unable to start activity ComponentInfo{nightradio.sunvox/nightradio.sunvox.MyNativeActivity}: 
java.lang.IllegalArgumentException: Unable to find native library: sundog
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2070)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2095)
at android.app.ActivityThread.access$600(ActivityThread.java:134)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1203)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4830)
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:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
at dalvik.system.NativeStart.main(Native Method)
...

I can't understand why. The app have all necessary libraries in the armeabi, armeabi-v7a and x86 folders. And it has been tested on many devices with different architectures.

android:hasCode="true" option exists.

Also i noticed, that the most of these problematic devices has Rockchip CPU (RK3066, RK2928, RK2926). But not all. The latest one has Huawei K3V2 CPU and a lot of free memory. Another Native Activity apps (not mine) don't work on the latest device too.

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
NightRadio
  • 101
  • 1
  • 4
  • Any chance of getting the log messages right before the exception? There's probably an error message from `dlopen()`. – fadden Dec 14 '13 at 15:42
  • I will try. But what the best way to do it? I always used the Log Collector with Android 2.3. But with the latest Android versions the log is very very short for some reason. Seems that there is some system limit for the log size or so. – NightRadio Dec 14 '13 at 16:21
  • If a device fails to load the library, is it 100% reproducible? – Alex Cohn Dec 14 '13 at 19:50
  • You can check if the library is installed by `adb shell ls -l /data/data/nightradio.sunvox/lib` – Alex Cohn Dec 14 '13 at 20:08
  • Yes, it is 100% reproducible. But it is not my device, so i'm afraid that the user doesn't know what is adb :) – NightRadio Dec 15 '13 at 05:02
  • @Yogi `inline code` is NOT for syntax highlight, it's for... well, code. For highlight we have **bold** or *italics*. Please don't do such edits. See [this meta discussion](http://meta.stackexchange.com/q/135112/152859) for more details or if you want to express different opinions. – Shadow The GPT Wizard Jan 02 '14 at 07:20
  • @Shadow Wizard Yeah you are right i observed it later..thanks for pointing out – Yogesh Jan 02 '14 at 07:24
  • 1
    You are most likely facing 2nd-rate devices with broken android installs that are confused as to their architecture. – Chris Stratton Jan 02 '14 at 08:10
  • Did you try to force loading all libraries manually by using System.loadLibrary() ? – Mustafa Güven Jan 02 '14 at 11:18
  • @MustafaGüven no, but i will try the way described by paulscode below – NightRadio Jan 02 '14 at 15:23
  • 1
    @NightRadio, I feel bad getting the bounty by default, since my answer isn't a direct solution to the problem (more of a way to debug the problem). I'll see if I can find an app tester who has one of those devices, to try and post an actual solution for you. If one of your users doesn't mind work with me, just shoot me a message with their contact info (you can find me by Googling "paulscode") – paulscode Jan 03 '14 at 13:05

1 Answers1

4

You will need to read the logcat output to see what happened prior to the crash, which prevented the native library from loading. I use Acra for my apps (generates crash reports containing logcat output), but as a quick solution to get the logcat output without implementing a whole crash reporting system, you could use something like this in a test build, and have the user run it:

try
{
    Process process = Runtime.getRuntime().exec( "logcat -d" );
    BufferedReader bufferedReader = new BufferedReader(
        new InputStreamReader( process.getInputStream() ) );
    StringBuilder log = new StringBuilder();
    String line = "";
    while( ( line = bufferedReader.readLine() ) != null ) {
        log.append( line );
    }
    // Output available via log.toString().. do whatever with it
} 
catch( IOException e ) {}

If you look at the source code for NativeActivty, this exception you are seeing gets thrown in the onCreate() method (see line 171), so if you override that method in a derived class of NativeActivity, you can catch it and grab the logcat output from there. Then you could save the log to a file and have a user with an affected device run the test and email the file to you, for example.

Another good thing about overriding onCreate(), is it will also allow you to reproduce some of what goes on behind the scenes, with more debug logging to help you track down the problem.

paulscode
  • 1,049
  • 1
  • 12
  • 29
  • 2
    You may also find this little hack helpful, when debugging overridden methods of NativeActivity: http://stackoverflow.com/a/8261608/1002212 – paulscode Dec 31 '13 at 16:02
  • 2
    thank you! Finally it works now! But i can't understand why :) I only added this code to the main class (based on NativeActivity): `@Override protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); }` – NightRadio Jan 04 '14 at 18:40