Android how to module (Library) to call main app function? - android

I try to call a module (Library) in my MainActivity class. How do I easily call it?
I am also trying to use:
implementation project(':app')
but it is not working--I get Gradle errors.

First off, NOBODY should call a function on an Activity. Because nobody should have an instance of the Activity (an instance of Context sure, but not the activity). Secondly, you can't have a cycle in your build graph. If module A depends on B, then B can't depend on A. Refactor your code so this isn't necessary.

Related

Library API with Activity as entery point - how to provide result to main module?

We create a library which entry point is an Activity. There's a lot going on inside, and finally we need to return something to the main module. We want also to enter to this Activity from the notification. This can be done through the Indirect Activity.
Now there are 4 options for passing data back to the main module:
startActivtyForResult
Passing the Intent to be called after the end of the process in the module
StateFlow issue that will allow you to observe the process status in the module
Passing callbacks to the library and storing them somewhere in Singleton.
What would you choose?

launch activity in library module from main module

I have 2 different modules, module A and module B is library module. In module A, there is a button that will launch activity library module B when user click the button. How do i link the button to launch activity in module B?
You can pass the package name in the Intent like this:
Intent intent = new Intent(YourClassA.this, com.your.package.name.ClassB.class);
startActivity(intent);
There's two scenarios I see here:
Scenario #1:
Module A includes module B in its build.gradle file. If so, module A can directly start the Activity because the Activity is visible to it. This would be (in Kotlin):
button.setOnClickListener {
val intent = Intent(this, ActivityInModuleB::class.java)
// Possibly add extras here
startActivity(intent)
}
Scenario #2:
Module A does NOT include module B, but both are in the same project. In this case, the ActivityInModuleB class would not be visible to module A, so you could not import it and use it directly. In this case, there's a few possible solutions...
Option #1:
Use <activity-alias> in your AndroidManifest.xml for module B to associate ActivityInModuleB to a string. Then you can create the Intent in module A and call intent.setAction(actionStringInManifestGoesHere) and thus you can indirectly refer to this class.
I personally haven't used this approach, though I wanted to in a previous project. It's just that that project was already using option #2 and it would have taken a while to switch over.
Option #2:
Setup a LocalBroadcastReceiver in a module that includes both module A and module B. Then, each module can register themselves as handling broadcasts. When a broadcast is sent, an action is attached (similar to option #1). The broadcast receiver will call each module's handler and give it an opportunity to start the appropriate Activity, if it finds the associated action in its supported list. At the point a module starts an Activity it can return true to say it handled the action and your main module can decide to either short circuit calling any other modules' handlers OR let all modules have an opportunity.
This approach definitely works (it's used in an app with millions of installs). BUT, I think it's basically just recreating option #1, so probably is overkill.

android.content.res.Resources$NotFoundException. Module, aar library

I have library module with string resource.
string.xml
<string name="lib_ver">1.0</string>
and method:
public static String getLibVersion(Context context){
return context.getResources().getString(R.string.lib_ver);
}
In my app application i include my module like aar library.
Everything work properly except 1 thing.
if i try to get lib version with lib method in activity class:
getLibVersion(getApplicationContext()) i get error:
android.content.res.Resources$NotFoundException: String resource ID
#0x7f02105b
But if i do in activity class, without call to library method:
getApplicationContext().getResources().getString(R.string.lib_ver)
There is no errors. Where is a problem? Thx.
just need to update gradle to 2.1.2
classpath 'com.android.tools.build:gradle:2.1.2'
getApplicationContext: Return the context of the single, global Application object of the current process. This generally should only be used if you need a Context whose lifecycle is separate from the current context, that is tied to the lifetime of the process rather than the current component. From android
That might be the reason that your ApplicationContext is throwing error! :)
More info:
Context and ApplicationContext are both instances of Context, but the application instance is tied to the lifecycle of the application, while the Activity instance is tied to the lifecycle of an Activity. Thus, they have access to different information about the application environment.
If you read the docs at getApplicationContext it notes that you should only use this if you need a context whose lifecycle is separate from the current context. This doesn't apply in either of your examples.
The Activity context presumably has some information about the current activity that is necessary to complete those calls. If you show the exact error message, might be able to point to what exactly it needs.
But in general, use the activity context unless you have a good reason not to.

Dagger2 Component as Static Global Variable

My Android app has multiple activities. The MainActivity constructs a Dagger2 component in its onCreate() method and assigns it to a static variable so any class can call the static method MainActivity.getDaggerComponent() to then inject itself with dependencies.
The problem I'm discovering is that when I start up my VideoPlayerActivity, the MainActivity object sometimes gets its onPause() invoked. If this happens, the static component variable gets set to null. At a later point, VideoPlayerActivity needs to inject its dependencies, but there is no component so things blow up.
How does one ensure that a Dagger2 component is available at all times for all activities?
Initialize Dagger component in Application class or just statically. It might be that you're doing a very wrong thing trying to use dependencies of one Activity in another Activity. This might create memory leaks and in particular sounds like a design problem. What if your first Activity was already destroyed? Who will free up the Dagger instance? Why graph belongs to first Activity and not to the second one? What if user will enter your app from the second Activity - then first one won't be even initialized. And so on, and so on.
If you still need Activity instance, then you should use Activity specific component within the Activity and move everything else in global (Application wide) component.

get onResume/onPause/onDestroy from non activity

There is a class in a library that is called from javascript (html5 app). It can't be an Activity extender.
The class has access to Activity and WebView objects.
Is it possible to get onResume, onPause and onDestroy activity events from this library class?
On API Level 14+, you can call registerActivityLifecycleCallbacks() on your Application instance to find out about all callbacks to all activities in your app.
Or, modify your Activity to call the class in the library on each of those callbacks.
Mouse right click Source --> Override/Implement Method you can find methods which you need it. But make sure add your library on your project

Categories

Resources