apsun / RemotePreferences

A drop-in solution for inter-app access to SharedPreferences.
MIT License
138 stars 32 forks source link

Unable to get provider #16

Closed git360Flip closed 3 years ago

git360Flip commented 3 years ago

Hello, first of all, thanks you for your good work!

I just followed multiple times the installation guide, and I double-checked this by comparing to the testapp, I can't start my application with RemotePreferences because of a problem with provider.

In Manifest.xml:

<provider android:authorities="com.myapp.test.preferences" android:name=".MyPreferenceProvider" android:exported="true" />

In Java/com.myapp.test folder, MyPreferenceProvider Class:

public class MyPreferenceProvider extends RemotePreferenceProvider { public MyPreferenceProvider() { super("com.myapp.test.preferences", new String[] {"test"}); } }

And when I compile it: java.lang.RuntimeException: Unable to get provider com.myapp.test.MyPreferenceProvider: java.lang.ClassNotFoundException: Didn't find class "com.myapp.test.MyPreferenceProvider" on path .... blablabla

I'm sure that's a easy fix but I can't find on internet a solution for this particular problem with your library. If you need any other information, I can give it to you. Thanks you for helping me and have a good day!

EDIT: I think it's comes from Xposed, i'm using the v90-beta3 and the first errors logs after ClassNotFoundException is at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:361)

Complete error: 2021-01-17 02:07:07.810 10188-10188/com.myapp.test E/AndroidRuntime: FATAL EXCEPTION: main Process: com.myapp.test, PID: 10188 java.lang.RuntimeException: Unable to get provider com.myapp.test.MyPreferenceProvider: java.lang.ClassNotFoundException: Didn't find class "com.myapp.test.MyPreferenceProvider" on path: DexPathList[[zip file "/data/app/com.myapp.test-uibVPddJ9zeWqq_LXlkdFg==/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp.test-uibVPddJ9zeWqq_LXlkdFg==/lib/x86, /system/lib, /system/vendor/lib]] at android.app.ActivityThread.installProvider(ActivityThread.java:6288) at android.app.ActivityThread.installContentProviders(ActivityThread.java:5851) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5772) at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method) at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:361) at android.app.ActivityThread.handleBindApplication(<Xposed>) at android.app.ActivityThread.-wrap1(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1661) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6541) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:108) Caused by: java.lang.ClassNotFoundException: Didn't find class "com.testapp.test.MyPreferenceProvider" on path: DexPathList[[zip file "/data/app/com.testapp.test-uibVPddJ9zeWqq_LXlkdFg==/base.apk"],nativeLibraryDirectories=[/data/app/com.testapp.test-uibVPddJ9zeWqq_LXlkdFg==/lib/x86, /system/lib, /system/vendor/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at android.app.ActivityThread.installProvider(ActivityThread.java:6273) at android.app.ActivityThread.installContentProviders(ActivityThread.java:5851)  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5772)  at de.robv.android.xposed.XposedBridge.invokeOriginalMethodNative(Native Method)  at de.robv.android.xposed.XposedBridge.handleHookedMethod(XposedBridge.java:361)  at android.app.ActivityThread.handleBindApplication(<Xposed>)  at android.app.ActivityThread.-wrap1(Unknown Source:0)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1661)  at android.os.Handler.dispatchMessage(Handler.java:105)  at android.os.Looper.loop(Looper.java:164)  at android.app.ActivityThread.main(ActivityThread.java:6541)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)  at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:108)  Suppressed: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/crossbowffs/remotepreferences/RemotePreferenceProvider; at java.lang.VMClassLoader.findLoadedClass(Native Method) at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738) at java.lang.ClassLoader.loadClass(ClassLoader.java:363) ... 16 more Caused by: java.lang.ClassNotFoundException: Didn't find class "com.crossbowffs.remotepreferences.RemotePreferenceProvider" on path: DexPathList[[zip file "/data/app/com.testapp.test-uibVPddJ9zeWqq_LXlkdFg==/base.apk"],nativeLibraryDirectories=[/data/app/com.testapp.test-uibVPddJ9zeWqq_LXlkdFg==/lib/x86, /system/lib, /system/vendor/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:93) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) ... 19 more

apsun commented 3 years ago

From what I can tell from the stacktrace, it seems like the Xposed hook is being applied to the same process where the preference provider is running. This is a strange setup, since you could have just used a plain old SharedPreferences to do this. Can you explain the setup you are trying to achieve, and how you are actually calling the RemotePreferences API? (A minimum reproducible example would be great)

git360Flip commented 3 years ago

Wow thanks you for your quick reply!

My applications contains 3 important classes:

I have found solution with Su requests for forcing read access from other applications to SharedPreferences of mine, and by this way, XSharedPreferences works, but this is really unstable and not the solution that I will use. (When an application wants to read SharedPreferences of mine, a SU request from this application is sended for the chmod and this is really not good)

Thanks you for your help, I really appreciate that :)

apsun commented 3 years ago

Right, the issue I see is that it looks like you hooked handleBindApplication inside the app where the RemotePreferenceProvider is. If you try to use RemotePreferences within that hook, it will end up with infinite recursion. That said, that doesn't seem to be the case here, so I'll ignore it for now.

Since it's throwing ClassNotFoundException, can you check if you have ProGuard enabled? If so try disabling it; I think it should be smart enough to ignore things defined in the manifest, but maybe not.

If that doesn't help, please upload the code of your app, without more info I can't really tell what's going on. Thanks.

git360Flip commented 3 years ago

I don't hook the handleBindApplication in my XposedClass on my application.

I'm currently trying to disable ProGuard in Android Studio.

There is an update: With the same setup (I just moved the declaration of RemotePreferences inside a afterHookedMethod on the HandleLoadPackage of my XposedClass on my application): SharedPreferences prefs = new RemotePreferences(AndroidAppHelper.currentApplication(), "com.myapp.test.preferences", "test");

Now this line give me that error when i'm using outside of my application a hookedMethod: 2021-01-17 04:30:35.795 6709-6709/com.android.dialer E/Xposed: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/crossbowffs/remotepreferences/RemotePreferences; at com.myapp.test.XposedClass$8.afterHookedMethod(XposedClass.java:280)

I think it's because inside Hook we are in the other application Context and this application didn't load the RemotePreferences Library.

My application crash at launch now with this error: Rejecting re-init on previously-failed class java.lang.Class<com.myapp.test.MyPreferenceProvider>: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/crossbowffs/remotepreferences/RemotePreferenceProvider

Do you have any idea to make it works ? Thanks you

apsun commented 3 years ago

Probably either ProGuard or your build setup is misconfigured. Again, without the code I can't really say.

git360Flip commented 3 years ago

Ok, thanks you for your time. Because I'm really new to develop android app, I will give you in one hour my entire project with Github

git360Flip commented 3 years ago

And there you go: https://github.com/git360Flip/TestXposedRemotePreferences I keep the code very minimalist for only checking what is not working :)

UPDATE: It's seems to works! I really don't know why I just re wrote this project in 30 minutes.. I'm currently trying to understand why this project works and not my original one, I will tell you when I found it

git360Flip commented 3 years ago

Ok I just found it:

In my build.gradle (app) I was using this line:

compileOnly 'com.crossbowffs.remotepreferences:remotepreferences:0.7'

I just replace it by:

implementation 'com.crossbowffs.remotepreferences:remotepreferences:0.7'

Like I said i'm really a beginner at Android Development and Xposed and I didn't know that we have to use implementation instead of compileOnly that I have to use for Xposed

Thanks you for your help, and for your useful library :)

apsun commented 3 years ago

Ah, I didn't realize the readme is still using the deprecated compile directive (rolls eyes)... Yeah compile translates to implementation, not compileOnly (who thought that was a good idea?!) Let me fix that, sorry about the confusion!