dagger android support to androidx.fragment - dagger-2

How to inject a fragment from the package androidx.fragment.app.Fragment ?
I'm using the dagger-android framework to inject my dependencies in my code.
As the documentation says I do this to inject my fragment
#Override
public void onAttach(Activity activity) {
AndroidInjection.inject(this);
super.onAttach(activity);
// ...
}
the problem is that AndroidSupportInjection class accept only fragments of the package android.support.v4.app.Fragment or if I use AndroidInjection class only accept fragments of the package android.app.Fragment and I want to use fragments of the androidx.fragment.app.Fragment package.
Also DaggerFrament extend from android.support.v4.app.Fragment and want to use a fragment from androidx
And If I try to implement HasSupportFragmentInjector also this interface use a fragment from android.support

add the below code to your gradle.properties
android.useAndroidX=true
android.enableJetifier=true
And if you are trying to inject into a Fragment you have to replace AndroidInjection.inject(this) with AndroidSupportInjection.inject(this)

I had the same problem in case of HasFragmentInjector. You need to use HasSupportFragmentInjector for fragment injection. This is because, HasFragmentInjector uses android.app.Fragment which is not effected by jetifier. You need to add android-dagger-support library, jetifier converts all the support packages to androidx in Studio 3.3 (if jetifier is enabled).
If jetifier does not change support packages to androidx packages. You can download jetifier tool from here and convert the android-dagger-support.aar file manually by using the following command.
./jetifier-standalone -i dagger-android-support-<version>.aar -o <output-name>
Then add the library to your project. This is the HasSupportFragment class after conversion
import androidx.fragment.app.Fragment;
import dagger.android.AndroidInjector;
public interface HasSupportFragmentInjector {
AndroidInjector<Fragment> supportFragmentInjector();
}
Somehow, jetifier tool was not converting libraries in AndroidStudio.
I had to do it manually.

I had a similar error and it was due to the Dagger version. On version 2.17 there is an strange issue, but if you roll back to version 2.16 it compiles perfectly (apart from the flags on gradle.properties that Paul posted).
From there using the tutorials you won't have trouble. Forgot to mention that on my project I had the non-androidX version of everything, then I ran the androidX migration that android studio offers, and after that I had to switch the Dagger version, but I suppose that if you do it from the start it's the same.
Hope this helps, if you switch and it doesn't work, post a little bit of your dagger implementation and plugins versions and I will try to help more!

Add the following to your gradle.properties file
android.useAndroidX = true
android.enableJetifier = true

Just for reference. i had the same problem. It was Jetifier issue. please upgrade your gradle build tools plugin to 3.3.0
classpath 'com.android.tools.build:gradle:3.3.0'
Sample code: https://github.com/jega-ms/android-dagger2-mvp-rx

This is what I did to work with androidx namespace for Dagger 2.21
Downloaded the jetifier tool from here: https://developer.android.com/studio/command-line/jetifier
Unzip into a folder and open a terminal pointing into the extracted bin folder
From Android Studio, open a class like DaggerFragment to check the path where the file is stored, for me (in MacOS) is something like this:
From terminal execute this command (replacing with the correct variables and path)
./jetifier-standalone -i /Users/{YOUR_USER}/.gradle/caches/{PATH_TO_DAGGER_ANDROID_SUPPORT_FOLDER}/dagger-android-support-2.21.aar -o dagger-android-support-2.21.aar
The converted dagger-android-support-2.21.aar will appear in your bin folder
Now open your app build.gradle file and change this line
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
adding the , '*.aar' part in the include array
Move the generated dagger-android-support-2.21.aar from bin to libs folder inside your project.
Remove (or comment) this line from the dependencies
implementation "com.google.dagger:dagger-android-support:2.21
Now you can proceed invalidating the cache and rebuild the project and now DaggerFragment will point to your converted version which uses androidx.fragment.app.Fragment
NOTE: Obviously this is a temporary workaround and you should move to the official version as soon this is fixed in Dagger

The solution to my particular problem was to use android dagger classes as interfaces instead of extend of them:
class MyFragment() : HasSupportFragmentInjector {
#Inject
lateinit var childFragmentInjector: DispatchingAndroidInjector<Fragment>
override fun onAttach(context: Context?) {
AndroidSupportInjection.inject(this)
super.onAttach(context)
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return childFragmentInjector
}
........
}
To my Activities
class MyActivity : HasSupportFragmentInjector {
#Inject
internal lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> = fragmentInjector
......
}
and also I have this in my gradle.properties file:
android.useAndroidX = true
android.enableJetifier = true

Related

Can not declare dependency to bblanchon/ArduinoJson in my library.json (platform io)

I am creating a platform IO library for one of my projects, which depends on ArduinoJson from bblanchon.
I have declared the dependency in my library.json file (both with the name as well as with the git repository as reference - see below). But when I try to compile a project that is using my library, the ArduinoJson library is not added to the dependency tree and compiling fails as the header file ArduinoJson.h is not found.
If I add the ArduinoJson as a dependency to the platformio.ini it is added to the dependency tree and the software compiles without issues. However this is not a clean solution and I want to now how I should declare the dependency in my library so that I do not have to add ArduinoJson to every project I build with this library.
Do you have any ideas how I can make this work?
Thx Christian
Declaration of dependency as suggested by pio library finder:
"dependencies" :
{
...
"bblanchon/ArduinoJson" : "*"
}
As reference to the repository
"dependencies" :
{
...
"bblanchon/ArduinoJson" : "https://github.com/bblanchon/ArduinoJson.git"
}
This one had me going for a bit as well. Here are the steps I took to solve.
Add to platformio.ini:
lib_deps = Arduino-libraries/Arduino_JSON # 0.1.0
Verify that you have the folder /.pio/libdeps/Arduino_JSON
Use #include <Arduino_JSON> in you code.

eclipse ResolutionException: Modules A and B export package P to module C

I try to migrate my java8 spring project to java11. Now I get the following exception when I try to run it from eclipse:
Error occurred during initialization of boot layer
java.lang.module.ResolutionException: Modules java.activation and jakarta.activation export package javax.activation to module spring.boot.starter.web
Under Referenced Libraries I only found jakarta.activation-api-1.2.2.jar which exports the package javax.activation. The other module java.activation I have no clue where it comes from. From the name it should be inside JavaSE-11/JDK ? I checked the entry JRE System Library but I don't see that package there.
Now the curios thing is with Gradle 6.5 I can run the project using "gradlew bootRun" and it executes nicely. However in eclipse it fails with the errror.
So in eclipse I just tried to remove Jakarta.activation by Right-click remove from build path. Trying to import anything from javax.activation then gives me "import can't be resolved", fine so far. However running still complains with the above ResolutionException.
So to fix the issue:
Where is the other sourcecode that exports javax.activation package? And how do I find that?
How can I prevent eclipse from having those two modules at runtime?
Can I exclude the module in gradle, such that the project works after running "gradlew eclipse" like always?
Thanks for your help! I spent hours searching and didn't find anything useful so far.
The build.gradle looks as following:
plugins {
id 'org.springframework.boot' version '2.2.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
id 'eclipse'
}
group = 'example'
version = '0.3.0'
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
configurations.all {
// fix multiple slf4j dependencies are present
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
//TODO: 1st approach to fix ResolutionException
//exclude group: 'jakarta.activation', module: 'jakarta.activation-api'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:2.3.1.RELEASE'
implementation ('org.springframework.boot:spring-boot-starter-web:2.3.1.RELEASE') {
//TODO: 2nd approach to fix ResolutionException
exclude group: 'jakarta.activation', module: 'jakarta.activation-api'
}
implementation 'org.springframework.boot:spring-boot-starter-security:2.3.1.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.3.1.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-actuator:2.3.1.RELEASE'
implementation 'mysql:mysql-connector-java:5.1.46'
implementation 'com.querydsl:querydsl-jpa:4.1.4'
implementation 'com.querydsl:querydsl-apt:4.1.4:jpa'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'org.flywaydb:flyway-core:5.2.4'
compileOnly 'org.springframework.boot:spring-boot-devtools:2.3.1.RELEASE'
// https://mvnrepository.com/artifact/org.apache.odftoolkit/simple-odf
implementation 'org.apache.odftoolkit:simple-odf:0.8.2-incubating'
// https://mvnrepository.com/artifact/org.apache.commons/commons-text
implementation 'org.apache.commons:commons-text:1.1'
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
implementation 'org.apache.commons:commons-lang3:3.7'
// https://mvnrepository.com/artifact/org.apache.commons/commons-csv
implementation 'org.apache.commons:commons-csv:1.5'
// https://mvnrepository.com/artifact/org.apache.commons/commons-collections4/4.3
implementation 'org.apache.commons:commons-collections4:4.3'
implementation 'javax.validation:validation-api:2.0.0.Final'
// Dependencies that are no longer in java11
// implementation 'javax.xml.bind:jaxb-api:2.3.0'
// implementation 'com.sun.xml.bind:jaxb-core:2.3.0'
// implementation 'com.sun.xml.bind:jaxb-impl:2.3.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.5.2'
}
eclipse {
classpath {
downloadJavadoc = true
downloadSources = true
}
}
Other links I found but didn't help me so far:
https://dba-presents.com/index.php/jvm/java/159-error-java-module-xyz-reads-package-org-apache-commons-logging-from-both-commons-logging-and-jcl-over-slf4j
Modules A and B export package some.package to module C in Java 9
Two Modules exports the same package (Spring)
https://forum.byte-welt.net/t/resolutionexception-module-a-module-b-to-module-c/20843/2
Ok I found part of an answer while trying to create an example to reproduce the issue.
First I tried to clean the project to make sure nothing bad is cached in eclipse:
gradlew clean eclipse
Still the problem occured.
Now I went full ham and removed all build files, .project, .classpath and reran gradlew eclipse and while adding a new run configuration the project now starts fine.
So probably blame the cache of the run-configuration.
Maybe this or the cross-links to other posts about the same issue still helps someone.

Does PostSharp add code during precompilation of assembly?

When assembly using PostSharp [Log] aspect was decompiled, the decompiled code appeared without new code added to it. Doesn't PostSharp add code corresponding to aspect during precompilation?
PostSharp post-processes the compiler output by reading and disassembling the intermediate assembly, execute the required transformations and validations, and rewriting the final assembly to disk.
PostSharp integrates itself in the build process via PostSharp.targets. NuGet adds the PostSharp.targets import to your project when you install PostSharp nuget package.
Let's consider this method:
[Log]
public void Method() { }
If everything works correctly then the decompiled C# code of this method starts like this (PostSharp 5.0):
public void Method()
{
bool flag = <>z__Program.DefaultCategory.IsEnabled(LogLevel.Debug);
LogMemberInfo logMemberInfo;
If you don't see this code, it may indicate that PostSharp is not correctly installed to your project or it is not correctly configured.
Adding Detailed Logging to your Solution article explains how to correctly configure and add PostSharp to your project.

how to import javax.swing in android studio

I have just setup Android Studio and started a simple application. Well started is an over statement, I got stuck on first few lines and am unable to import JFrame into android studio.
I have the latest SDK installed aling with LibGDX. I am still not able to setup JFrame. I have searched the net/youtube and no solutions have been found.
I can see the javax and swing in my external libraries but just cannot import.
Any ideas what I am doing wrong or not doing?
I am not looking for a "how to tutorial", I just a pointer where I should go hunting for the answer.
wow, not huge amount of response.
Please advise if I have asked a stupid question or difficult question.
public hungryDog() {
JFrame jframe = new JFrame();
Timer timer = new Timer(20, this);
renderer = new Renderer();
rand = new Random();
jframe.add(renderer);
jframe.setTitle("Hungry Dog");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setSize(WIDTH, HEIGHT);
jframe.addMouseListener(this);
jframe.addKeyListener(this);
jframe.setResizable(false);
jframe.setVisible(true);
dog = new Rectangle(WIDTH / 2 - 10, HEIGHT / 2 - 10, 20, 20);
columns = new ArrayList<Rectangle>();
addColumn(true);
addColumn(true);
addColumn(true);
addColumn(true);
timer.start();
}
You can't use Swing on Android. Android has its own UI framework which is different, and Swing isn't supported. To see what Java APIs are supported on Android look at the API docs at http://developer.android.com/reference/packages.html
I used to have the same problem; here's how to solve it.
You see, we were trying to use swing lib in a totally wrong context, that is, within an Android app. As Scott Barta pointed out, Android has its own mechanisms for doing what we wanted to achieve and that's why IntelliJ didn't let us import anything that would interfere with Android API.
Hence, do NOT use Android app when, say, simply learning how to code in Java or, on a more advanced level, when testing/debugging your algorithms. Instead, build a standalone Java program (yes, in Android Studio). This very topic is covered here: Can Android Studio be used to run standard Java projects? , "Tested on Android Studio 0.8.6 - 1.0.2" by idunnololz). A few clarifying remarks to this solution:
1) wnen preparing your configuration (Run | Edit Configurations...), use your new Java module name and its main class in the appropriate fields.
2) before clicking Run make sure you selected same configuration.
Incidentally, there indeed IS a way to import swing library into any Android app: based on http://www.youtube.com/watch?v=fHEvI_G6UtI. Specifically, add a new line to build.gradle file for your Module:app:
compile files ('<path_to_your_jdk's_rt.jar>')
Like this:
compile files ('C:/Program Files/Java/jdk1.8.0_31/jre/lib/rt.jar')
Note single quotes and forward slashes. Then click Sync Gradle icon and enjoy the view.
In our particular case, however, the program won't run. The code itself will be clean, there'll be no errors; with swing lib well in place and connected, IntelliJ won't suspect a thing; the project WILL compile... but then we'll get a runtime error. Now your know why. On the other hand, this method works like magic when we do not interfere with Android API --- which we shouldn't in the first place.
That's all there is to it.
Yes you can. As addition to Igor's answer here are the steps:
Create new Android Studio project: File -> New -> New Project -> Phone and Tablet -> Add No Activity, select Java (not Kotlin) as language obviously.
Add new Java module: File -> New -> New Module -> Java Library
Remove Android module: File -> Project Structure -> Modules -> app, click - button.
NOTE: step 5 is probably not needed. Try without it first.
Edit build.gradle of your java module, and add in dependencies implementation fileTree pointing to the JRE you need.
Example of build.gradle:
apply plugin: 'java-library'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation fileTree ('/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/rt.jar')
}
sourceCompatibility = "6"
targetCompatibility = "6"
Now code completion works and you can even run the app:
Click on Add Configuration: near run button
Click on + -> Application
Select your Main Class
At Use classpath of module: select your java module there (not project's)

Get a custom Gradle plugin's version from its own code

I wrote a Gradle plugin, its version is specified in its build script.
It is possible for this plugin to be aware of its own version when someone is using it? (i.e. when its apply(Project project) method is called)
For my plugins, I embed a field into the MANIFEST.MF file called Implementation-Version during build. Then I read that field in during runtime, by accessing the package like this:
def pkg = MyPlugin.class.getPackage()
return pkg.implementationVersion
Or using a helper class like: https://github.com/nebula-plugins/nebula-core/blob/master/src/main/groovy/nebula/core/ClassHelper.groovy#L16 to grab arbitrary field from the manifest.
You can also find the version by doing this:
def selfVersion = project.buildscript.configurations.classpath.resolvedConfiguration.resolvedArtifacts.collect {
it.moduleVersion.id }.findAll { it.name == '<name of plugin>' }.first().version