pardom-zz / ActiveAndroid

Active record style SQLite persistence for Android
http://www.activeandroid.com
4.7k stars 1.03k forks source link

NPE in Cache getTableName #299

Open tomrozb opened 9 years ago

tomrozb commented 9 years ago

I'm looking into the crash reports for my app and I'm seeing a few crashes on the same line in ActiveAndroid.

Caused by: java.lang.NullPointerException
       at com.activeandroid.Cache.getTableName(ProGuard:156)
       at com.activeandroid.query.From.addFrom(ProGuard:169)
       at com.activeandroid.query.From.toSql(ProGuard:250)
       at com.activeandroid.query.From.executeSingle(ProGuard:311)

I've searched through the issues and it looks like it's common issue. I see it here: #291 #264 #109

One of my Activities can be started by 3rd party apps and one of the apps starts this activity within its own task. It's started from another process, but my activity is part of the 3rd party app backstack. Even though a new process is created for my app it sometimes crash on getTableName in Cache. The ActiveAndroid initialization code is places inside the onCreate method of the Application class.

Any clues what can be wrong? In my opinion looks like problems with static references in ActiveAndroid or the returned TableInfo is null. What about starting the exported activity from another process, could this be the problem (I don't think so, since a new process is created)?

daentech commented 9 years ago

I appear to be having a similar problem, except it seems to happen only when the activity is coming back after it has been left unopened for a while.

Caused by java.lang.NullPointerException
    at activeandroid.Cache.getTableName (Cache.java:156)
    at com.activeandroid.query.From.toSql (From.java:146)
    at com.activeandroid.query.From.execute (From.java:205)

I think it looks to me like the tableInfo is null. Does the cache ever get rebuilt?

tomrozb commented 9 years ago

happen only when the activity is coming back after it has been left unopened for a while.

Yes it happens to me also. It's rather a rare and hard to reproduce crash but occurs constantly with almost exactly the same stack trace (Cache.java:156). Maybe launching from a 3rd party app is not the problem at all, just pointed it out to present the whole picture.

daentech commented 9 years ago

Have you added each of the model classes explicitly to the AA instance? I've just done that (as mentioned in the other threads) rather than using the automatic model detection and I'll see if the crashes still appear.

Edit: It looks like it's still happening despite adding the classes manually.

tomrozb commented 9 years ago

@daentech How to add them? Please give me some links with an example and I'll try.

daentech commented 9 years ago

I have tried it like the following, but it hasn't worked for me:

Configuration.Builder configurationBuilder = new Configuration.Builder(getApplicationContext());
        configurationBuilder.addModelClasses(
                MyObject1.class,
                MyObject2.class
        );
        ActiveAndroid.initialize(configurationBuilder.create());
tomrozb commented 9 years ago

@daentech Will this configuration prevent from scanning the entire apk for classes which extends Model or it's just hint to use some classes and scan for others?

I'll try to add this in the next release and see if it helps in any way.

daentech commented 9 years ago

I think it still does the scan. At least, I added a couple of classes to it and it still managed to find the others. Let me know your results.

--  Dan Gilbert

dan.gilbert@smilemachine.com | GB:+447811 137065 | ES:+34 632064379 | Skype

Smile Machine, 16-22 Baltic Street West, 1st Floor, London, EC1Y 0UL www.smilemachine.com | @SmileMcn | Facebook | 0207 060 5100

Smile Machine Limited, registered in England and Wales, Company No. 07242537. Registered Office: Kemp House, 152 City Road, London, EC1V 2NX

On Fri, Nov 28, 2014 at 6:29 PM, Tomasz Rozbicki notifications@github.com wrote:

@daentech Will this configuration prevent from scanning the entire apk for classes which extends Model or it's just hint to use some classes and scan for others?

I'll try to add this in the next release and see if it helps in any way.

Reply to this email directly or view it on GitHub: https://github.com/pardom/ActiveAndroid/issues/299#issuecomment-64915755

tomrozb commented 9 years ago

Nothing has changed, I can still see in crash reports this occurs exactly on the same line.

daentech commented 9 years ago

In the end I've done a pretty horrible hack to mitigate it. Using an ExceptionHandler to catch it, deal with just that particular one by relaunching the app clean and it seems to work. I couldn't however recommend that method in good faith :)

tomrozb commented 9 years ago

I can confirm this is not related to activities or different processes. It happens even in Services so it must be a bug in ActiveAndroid. @pardom do you know what might be wrong here?

amolgupta commented 9 years ago

I added the config to the manifest file to indicate the scan but still got this issue <meta-data android:name="AA_MODELS" android:value="xxx.xxxx.entities.Notification, xxx.xxx.entities.ActivityLog" />

jlhonora commented 9 years ago

Did you also increase the AA_DB_VERSION number after adding the models to your manifest?

amolgupta commented 9 years ago

Yes I did. I even cleared the data for the app. Its happenning consistently unlike for others in this thread.

amolgupta commented 9 years ago

I am testing my code on a Android 5.0 device and a Android 2.3 emulator. It crashes only on 2.3. Will look for a 2.3 device and post the result here.

amolgupta commented 9 years ago

So far it has crashed on ALL emulator but NO actual device. Tested on various versions of emulators and devices.

pflammertsma commented 9 years ago

We're seeing this crash in some production code on devices in the wild. The snapshot I'm looking at includes 136 devices, and of those devices I see at least Android 4.3 through to 5.0.2, including stock Nexus 4.

My particular crash occurs on this line, which is called through a Loader:

Uri uri = mContext.getContentResolver().insert(
        ContentProvider.createUri(ZoneInformation.class, null), cv);

We have initialized ActiveAndroid in our Application's onCreate():

@Override
public void onCreate() {
    super.onCreate();
    ActiveAndroid.initialize(this);
    //...
}

I haven't had any luck reproducing it; it only happens in the wild.

tomrozb commented 9 years ago

I've tried to fix it but without luck. I'm afraid this project may already be abandoned. The last commit is dated to Oct 7, 2014, there are 149 issues and 40 pull requests. I don't think this issue will be fixed soon.

pflammertsma commented 8 years ago

I believe I can give some insight into this issue. I noticed that the way in which URIs were being added into AA's ContentProvider were localized strings. It appears that by switching to the Turkish locale, i was being converted (only in some cases) to ı (note the missing dot on the i).

In my case, the UriMatcher contained a match for parkingzoneınformation, but the URI it was trying to match against was content://com.parkmobile.debug/parkingzoneinformation.

I'm trying to get to the bottom of this and will follow up when I find the root cause.

pflammertsma commented 8 years ago

The underlying problem appears to be in AA's ContentProvider class, in the onCreate() on line 51 and 55:

URI_MATCHER.addURI(sAuthority, tableInfo.getTableName().toLowerCase(), tableKey);
...
URI_MATCHER.addURI(sAuthority, tableInfo.getTableName().toLowerCase() + "/#", itemKey);

Changing capitalization using the default locale's may yield bad results. In Turkish, a lowercase I is not i, but ı. From the example in my previous comment, my table was being case converted from ParkingZoneInformation, which revealed the underlying problem.

The simple solution is to change these lines respectively to:

URI_MATCHER.addURI(sAuthority, tableInfo.getTableName().toLowerCase(Locale.ENGLISH), tableKey);
...
URI_MATCHER.addURI(sAuthority, tableInfo.getTableName().toLowerCase(Locale.ENGLISH) + "/#", itemKey);

There's another instance of this bug in createUri():

uri.append(Cache.getTableName(type).toLowerCase(Locale.ENGLISH));

We've made the fixes in our fork of ActiveAndroid.

Here's the specific patch commit: https://github.com/Pixplicity/ActiveAndroid/commit/dbf35f42ddd91e2a4f7da16f6bde18b10db9051d