ClassLoader to replace a pre-loaded class? - android

General question:
Is it possible to use a ClassLoader to replace a pre-loaded (by the system, e.g. found in Android's %android%/frameworks/base/preloaded-classes file) class?
Specific:
I am attempting to use the DexClassLoader to replace a class found in android.net.* before creating a WebView in my application. I can get a Class object, but getMethods() for example gives me an array I'd expect in the unmodified/original class implementation. Is this due to the preloaded-classes system?
Basic setup & pseudo code:
Modify android.net.* class, adding a few test methods/etc.
Compile and end up with classes.dex
jar cf mytest.jar classes.dex
Include mytest.jar in APK assets
Create DexClassLoader and get Class via loadClass()
getMethods() on Class object returns an array I'd expect to see without modifications present in #1
I can provide more details on the setup I'm using and code if needed.

No you can not. WebView is part of the boot class path, and thus the base class loader. There is nothing you can do to make it use classes in another class loader. In fact, it has already been loaded and linked to the classes it uses before your app is even launched (as part of the zygote process pre-initialization).

Related

Subclassing com.android.okhttp.AndroidShimResponseCache in application

I want to subclass ResponseCache and use a subclass of com.android.okhttp.AndroidShimResponseCache as an internal delegate.
In particular I want to add a small pre-caching method to the class, similar to AndroidShimResponseCache.put, but with my own files in the Response to be cached.
Then I would make my class (that inherits from ResponseCache) the system default.
How can I access AndroidShimResponseCache in my code to subclass it in my application?
I'm not able to get it from any repo or library on my device.

Library class as return type for methods in aidl interface

In IPC to interpret data received the process should be knowing the Class structure. So i made a Library of all required classes which are all implementing Parcelable.
In library i have defined aidl files for all calsses and ensured that these file are present in JAR.
In application, i have created same aidl file and place in the same package name as in library.
In aidl file which contains method definitions no error is shown but in code section of Stub() i get that the Library class as return could not be found.
if i create the same library object inside the method it shows valid object, but something with it as return type.
so, i moved one of the class from library to application there is problem with this class.
What have i missed so that library classes are not recognized as return type.
Note: i edited the compiler created class file for aidl in gen folder and added import to my library, error is solved but i cant save it, compiler will overwrite it.
what a shame... Package name of classes in my library had first letter as capital while i messed it by creating package structure in my application with small letter...
Wont delete the Question. someone else might also do same mistake

Android/Java Standard Package names are they protected

I need to make a reference to a builtin Android Java Class in NDK c++ code.
You can do it by
cls_tm = (*env)->FindClass(env, "javax/crypto/Cipher");
I am worried someone can tamper with apk, extract the java code then create their own class with the package name javax.crypto.Cipher, and read all the sensitive data I am passing to it. I am new to Java and Android so I wanted to know if it is possible to create your own package with same name as built in packages like javax.crypto.Cipher?
It is possible to create classes with the same name. However, they do not take the place of existing classes.
Every class is loaded by a class loader. Class loaders form a hierarchy, with the "bootstrap" class loader at the very top. The class loader that loads your app's classes is created by the Android app framework; it is a child of the "system" class loader, which is a child of the bootstrap loader.
When your app references a class, it asks its class loader to find it by name. Each loader will either return a class that it defined, or ask its parent to find it. (The default behavior is to ask the parent first, but an individual loader can override this.)
javax.crypto.Cipher is part of core.jar, which is loaded by the bootstrap class loader. So unless your application's class loader decides to replace Cipher with its own version, you will get the system version.
(The JNI FindClass call is actually a bit strange. Depending on where you are when you call it, it can actually end up in the system class loader rather than your app's loader. See this section in JNI Tips for an explanation.)
Suppose you really did want to replace Cipher. You can provide your own version, and your app code will happily use it. However, when you try to pass it to some other code in core.jar, your app will fail. This is because classes loaded in the VM aren't unique by name, but rather by the combination of name and class loader. So you can't pass a Cipher+MyAppLoader into something that expects a Cipher+bootstrap.
In any event, if somebody modified your APK, they would have to re-sign it; since they don't have your private key, it wouldn't look like an app that came from you.
If somebody modified a device and replaced the system Cipher with their own version, they can do whatever they want.

Eclipse memory analyzer - help in find leak

I am trying to find memory leaks in my Android application.
I have the following situation:
class A created a class A$24 which created a thread. This thread has a reference to class A, so this is the leak.
I understand that A$24 is an anonymous class created in class A, but how can i find out where is was created, in which line in the code.
My problem is to understand who is the problematic thread.
In the project explorer of the resource perspective use the view menu, select "Customize view..." and uncheck "Inner class files" and "Java output folders". Now you should see the generated class files in the project explorer in a "bin" folder.
If you navigate to your A$24.class file, you can open it using a double click. Look for lines at the top talking about field selectors, like this
// Field descriptor #10 Z
private final synthetic boolean val$fStartMinimized
In this example, a final field fStartMinimized is used by the anonymous class (and therefore copied into the anonymous class). Using that field name you should be able to locate the anynomous class in question.
If there is no such field declaration (and also no method name giving you a clue), then you may get more insight with the ByteCode outline plugin (but I've never used that myself).

Android application plug-in architecture

I am experimenting with implementing plug-in architecture in Android, more specifically, cross-apk class loading
assume I have the following:
apk A and apk B, with the same sharedUserId defined in AndroidManifest.xml
interface I is defined in apk A, and apk B contains a class IB that implements I
I tried the following approaches
in apk A, use createPackageContext to obtain context of B, then call Context.getClassLoader and load the desired class name. However, due to the fact that this creates two class loaders, and therefore I cannot cast the class IB loaded in B into interface I; which means I need to use reflection...
pass apk B to DexClassLoader (path to apk B obtained by ApplicationInfo.sourceDir) and failed with "Class resolved by unexpected DEX", probably because there is a duplicate interface I in apk B as well...
modify build xml and follow the approach in Custom Class Loading in Dalvik to create a separate jar containing the class IB in B which implements I and put the jar into apk B's assets directory. This approach looks promising, as I can load class IB and cast it to I without problems. However, it creates the need for copying the jar, and I am not sure what will happen when NDK shared library is involved.
My question is, is there an approach that involves no modification of build.xml/ant.properties and works with NDK so library?
Not sure about other approaches, but for approach 2, you can exclude interface I when you were packing B to apk. Just exclude I.class file generated is enough.
You may find this post by Fred Chung helpful and may give you some hint. http://android-developers.blogspot.kr/2011/07/custom-class-loading-in-dalvik.html

Categories

Resources