Implement two(2) name spaces under Application in the Manifest file - android

I want to implement 2 name spaces under Application in android Manifest file to implement the firebase offline capabilities but it rejects taking 2 name spaces in the manifest file, see:
I tried to extend multiDexApplication in the MiLibrary Class, see:
public class MiLibrary extends Application {
#Override
public void onCreate() {
super.onCreate();
if (!FirebaseApp.getApps(this).isEmpty()) {
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
}
Picasso.Builder builder = new Picasso.Builder(this);
builder.downloader(new OkHttpDownloader(this, Integer.MAX_VALUE));
Picasso built = builder.build();
built.setIndicatorsEnabled(false);
built.setLoggingEnabled(true);
Picasso.setSingletonInstance(built);
}
but it gives me an error, see the stackTrace:
I've also tried searching here on stack-overflow and on Google but there are results or answers related to this, does anyone know how I can achieve this?

First of all in application tag you can define only single attribute for:-
android:name=".YourApplication"
Secondly, add the following dependency for okHttpClient:-
compile 'com.squareup.okhttp3:okhttp:3.2.0'
Your app's gradle file should look like this:-
defaultConfig {
...
minSdkVersion 14
targetSdkVersion //Yours
// Enabling multidex support.
multiDexEnabled true
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
}
Extend your application with MultiDexApplication class:-
public class MiLibrary extends MultiDexApplication { ... }
In your Manifest add name of your application as follows:-
<application
android:name=".MiLibrary"
...>

Related

DexOverflowException after adding com.google.firebase:firebase-firestore:11.4.2

I have a problem after adding compile "com.google.firebase:firebase-firestore:11.4.2" to my build.
As soon as I add that, it also adds com.google.common among other things to my dex file, which is around 27k extra references, thus bursting through the 64k dex limit.
Does anyone know why that is or am I doing something wrong?
Try adding these lines to your build.gradle
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 26
multiDexEnabled true
}
...
}
This will enable multidex mode, which will allow you to exceed the 64k limit. (Read more here)
API below 21
If you're using an API level below 21, then you also need to add the support library
gradle.build:
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
android.manafest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:name="android.support.multidex.MultiDexApplication" >
...
</application>
</manifest>
If you use a custom Application class, try using one the of the following
Solution 1
simply override the MultiDexApplication class
public class MyApplication extends MultiDexApplication { ... }
Solution 2
override attachBaseContext and install MultiDex using the install(Application) function
public class MyApplication extends SomeOtherApplication {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
You're not doing anything wrong: the Android API for Cloud Firestore is just big. We'll be working on reducing SDK size on the road to GA.
Meanwhile, you need to enable multidex to build if your application is nontrivial.
We actually use very little of com.google.common, so you may be able to say under the 64k method limit by proguarding your application too.
Updating to 11.6.0 fixes this issue

app crashed wiht classes.dex permission denied error

My app is crashed with following error,
E/dex2oat: Failed to create oat file:/data/dalvik-cache/arm/data#app#com.stvgame.xiaoy.remote-1#split_lib_dependencies_apk.apk#classes.dex: Permission denied
And our app use mutipule dex, does they have relation?
I had a similar problem and my solution was disable the Instant Run, if you're using Android Studio...
I had got a similar error when i used multi dex for the first time,
This guide helped a lot,
My error was i forgot to add this in the application class:
public class MyApplication extends SomeOtherApplication {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
in your build gradle, make sure you have included the following lines:
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 25
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
Even then multi dex has limitations with progaurd, read the guide to find out if that is causing this issue.

Create library without package dependency using Firebase Android SDK

Since we keep switching our backend depedencies (Previously parse, then backendless now firebase), I am trying to create a backend library for all my projects with adapters for specific backends and common interface to be used in the projects (Adapter Design pattern).
For example,
The backend library interface will have method,
save(User user)
and the adapters will have implementation to save the User in firebase or backendless, and I can easily switch
But the way the firebase sdk works, we need to have 'google-services.json' in our path with predefined 'package name', otherwise we would get the following error in gradle build,
Execution failed for task ':backend:processReleaseGoogleServices'.
No matching client found for package name 'com.lib.backend'
The error is obvious, as the google-services.json would have the packagename of the specific project.
So now is there a way or a procedure I could follow, where my projects will not use the 'Firebase' classes directly and it works only through the 'backend' library.
A simple combination of Bridge pattern and Dependency Injection should be enough. Create an interface in your app/library, create another library module which implement that interface using Firebase (with the plugin), and use DI in order to load your implementation. Whenever you want to change implementation, just replace this library module to some other implementation.
Edit: an example
We'll create a project with 3 modules:
Application module
Interface module (for reference from two other modules)
Firebase implementation of interface
You project should look like this:
Firebase module package name same as the app package name.
Next, we'll create the Firebase impl gradle file:
apply plugin: 'com.android.library'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.google.gms:google-services:3.0.0'
}
}
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 25
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile 'com.google.firebase:firebase-core:10.0.1'
compile 'com.google.firebase:firebase-database:10.0.1'
provided project(':proxylib')
}
apply plugin: 'com.google.gms.google-services'
In our app module gradle build file, we'll need to include both modules:
...
dependencies {
...
compile project(':firebaseproxy')
compile project(':proxylib')
}
And we'll put our google-services.json file in the firebase module dir:
Code is simple. The interface looks something like this:
public interface BackendProxy {
void save(String user);
}
And our Firebase implementation looks like:
public class BackendProxyImpl implements BackendProxy {
#Override
public void save(String message) {
FirebaseDatabase database = FirebaseDatabase.getInstance();
...
//save data to db
}
}
Note: I haven't tried actually implementing the database part, but it seems like it is running the google play gradle task. While it seems ok to me, I would have expect the google-play task to use the applicationId property, which is not available in the library module. If something is build wrong because of this, you'll have to run the google-play gradle task from the app module.

SugarORM + Multidex

I downloaded the SugarORM source to use it as a library module (so I could override the aplication's "attachBaseContext" method.
I have already seen the question SugarORM and multidex, Problem is that I can't figure out how to reference the MultiDex library into my new SugarORM library module.
Can someone help me figuring this out?
Error page screenshot
Create a class java file
public class MultiDex extends SugarApp {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
android.support.multidex.MultiDex.install(this);
}
#Override
public void onCreate() {
super.onCreate();
SugarContext.init(this);
}
#Override
public void onTerminate() {
SugarContext.terminate();
super.onTerminate();
}
}
In Manifest, call the java class file.
<application
.......
android:name=".MultiDex"
......>
Check the version of sugar library
and make sure you complie the latest version of sugar library . Using version like 1.3 will throw some errors with multidex.
add this in your gradle
compile 'com.github.satyan:sugar:1.5'
If possible, extend the MultiDexApplication yourself:
public class MyApplication extends MultiDexApplication
Also, ensure you have followed all steps required to configure MultiDex.
Particularly build.gradle:
android {
defaultConfig {
...
multiDexEnabled = true
}
And AndroidManifest.xml:
<application
android:name="android.support.multidex.MultiDexApplication"
.. >
..
</application>

Gradle and nested non-transitive dependencies

Here is a test project: click
I have a test Gradle Android project with three modules: app, library_a, library_b. app depends on library_a, then library_a depends on library_b:
build.gradle (app)
dependencies {
...
compile (project(":library_a")){
transitive = false;
}
}
build.gradle (library_a)
dependencies {
...
compile (project(":library_b")){
transitive = false;
}
}
Note that I set transitive = false because I don't want classes from library_b to be accessed from app
Every module has just one class, code is pretty simple:
app:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
//...
ClassA classA = new ClassA();
classA.doSomething();
}
}
library_a:
public class ClassA
{
public void doSomething(){
Log.i("Test", "Done A!");
ClassB classB = new ClassB();
classB.doSomething();
}
}
library_b:
public class ClassB
{
public void doSomething(){
Log.i("Test", "Done B!");
}
}
Well, here is the problem: I'm building my project with gradlew. Apk is compiling successfully, but when I run it I get NoClassDefFoundError.
I/Test﹕ Done A!
E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: ru.pvolan.library_b.ClassB
at ru.pvolan.somelibrary.ClassA.doSomething(ClassA.java:12)
...
If I set transitive = true in both .gradle files, it runs ok, but, as I noted above, I don't want dependency to be transitive, as far as I don't want ClassB can be accessed from MainActivity - only ClassA.
What am I doing wrong?
This is a problem that Gradle has simplified in Gradle v3.4.
If you convert library A to use v3.4 there is a simple fix.
Gradle 3.4 changes the "compile" configuration to a set of configurations "api" and "implementation".
First you should upgrade gradle to 3.4 and use the java-library plugin in lieu of the java plugin.
You should use the "api" configuration on any jar that is explicitly used in the API method calls (return type, input parameters, etc).
For all other jars that you want to "hide" (like Library B) you should use the "implementation" configuration. As Library B is only used within the body of implementation methods there is no need to expose it to any other jars at compile time; however it still needs to be available at runtime so Library A can use it.
To implement this your Library A script should replace
apply plugin: 'java'
dependencies {
...
compile (project(":library_b")){
transitive = false;
}
}
with
apply plugin: 'java-library'
dependencies {
implementation project(":library_b")
}
This change will tell Gradle to include Library B as a runtime dependency of app, so that app cannot compile against it, but Library B still will be available at runtime for Library A to use. If for some reason app ends up needing Library B in the future, it would be forced to explicitly include Library B in it's dependency list to ensure it gets the desired version.
See this description from Gradle itself for more details and examples:
https://blog.gradle.org/incremental-compiler-avoidance
The problem is that library_b is a required dependency. You can't simply exclude it, since you need it to be on the classpath at runtime. You are effectively misrepresenting your actual dependencies in order to enforce a code convention and therefore losing any advantage of leveraging a dependency management system like Gradle. If you want to enforce class or package blacklist I'd suggest using a source analysis tool like PMD. Here's an an example of a rule to blacklist specific classes.
If that is not possible for some reason you can get your above example to "work" by simply adding library_b to the runtime classpath of app.
dependencies {
runtime project(':library_b')
}
Do you use multidex?
When I had a problem like this I used multidex and called class from different module. I could fix it only by turning off multidex and running proguard.
UPD
android {
compileSdkVersion 21
buildToolsVersion "21.1.0"
defaultConfig {
...
minSdkVersion 14
targetSdkVersion 21
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
more about multi dex https://developer.android.com/tools/building/multidex.html
and about proguard http://developer.android.com/tools/help/proguard.html

Categories

Resources