I am trying to write some tests with classes that use roboguice. Unfortunately it seems that guice is not injecting anything at all.
My setup is like so...
I am using Intellij
I have 2 intellij modules (1 for code, 1 for tests)
I have 2 seperate module classes that extends AbstractModule(roboguice class) that define the bindings
I have 2 roboguice.xml files that point to the package like this...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="roboguice_modules">
<item>com.evertaletest</item>
</string-array>
</resources>
Does this setup seems correct? Any class that is injected is null at the moment
I believe the <item> entry needs to give the name of your module class, not simply the package.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="roboguice_modules">
<item>com.evertaletest.YourModuleForCode</item>
</string-array>
</resources>
But that will only be relevant for your production code. For tests, you will have to set your module in code instead of using XML.
In your test setup:
RoboGuice.setBaseApplicationInjector(application,
RoboGuice.DEFAULT_STAGE, new YourModuleForTest());
Related
I'm trying to create a custom attribute that behaves like tools:context, that is with
Android Studio auto complete functionallity
Project classname reference
Support for auto refactory in case I change my class directory
This is my resources.xml
<declare-styleable name="RecyclerView">
<attr name="adapter" format="string"></attr>
</declare-styleable>
This is the usage
<example.com.br.appname.RecyclerView
android:id="#+id/accounts"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
app:adapter="example.com.br.appname.AccountAdapter" >
</example.com.br.appname.RecyclerView>
I've tried to use the format reference but it didn't compile as well.
Error:(17, 22) String types not allowed (at 'adapter' with value 'example.com.br.appname.AccountAdapter').
I don’t think this is possible currently. Other similar custom attrs I can think of, for instance app:layout_behavior from the design library, or simply app:layoutManager from RecyclerView all require the full classname, with none of your requirements.
It might be better to store these in a strings resource file, and remember to check it when refactoring class names.
You can consider filing a feature request, since Android Studio has this functionality in special cases (tools:context, class in <view> and <fragment> tags, classes in Manifest...), but I doubt they would add a new attribute format just for this.
so...
apparently, YOU CAN!
Google does this too.
Android Studio understands that the class is being referenced from XML
i.e.
Refactor > Rename works
Find Usages works
and so on...
don't specify a format attribute in .../src/main/res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustomView">
....
<attr name="give_me_a_class"/>
....
</declare-styleable>
</resources>
use it in some layout file .../src/main/res/layout/activity__main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<SomeLayout
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- make sure to use $ dollar signs for nested classes -->
<MyCustomView
app:give_me_a_class="class.type.name.Outer$Nested/>
<MyCustomView
app:give_me_a_class="class.type.name.AnotherClass/>
</SomeLayout>
parse the class in your view initialization code .../src/main/java/.../MyCustomView.kt
class MyCustomView(
context:Context,
attrs:AttributeSet)
:View(context,attrs)
{
// parse XML attributes
....
private val giveMeAClass:SomeCustomInterface
init
{
context.theme.obtainStyledAttributes(attrs,R.styleable.ColorPreference,0,0).apply()
{
try
{
// very important to use the class loader from the passed-in context
giveMeAClass = context::class.java.classLoader!!
.loadClass(getString(R.styleable.MyCustomView_give_me_a_class))
.newInstance() // instantiate using 0-args constructor
.let {it as SomeCustomInterface}
}
finally
{
recycle()
}
}
}
In my Robolectric tests when calling getResources().getStringArray(R.array.some_array_id) I get a crash with Resources$NotFoundException.
This does not happen with other resource types, and it works in my app when running outside of tests.
The problem was how I had defined the array in resources, I used:
<array name="some_array_id">
</array>
I needed to use:
<string-array name="some_array_id">
</string-array>
Either one works fine with the real Android SDK but only string-array works with Robolectric.
I'd like to implement MvxRecyclerView, but I get following exception during runtime in SetContentView():
System.NotSupportedException: Could not activate JNI Handle 0x32700041
(key_handle 0xb29d17e8) of Java type
'mvvmcross/droid/support/v7/recyclerview/MvxRecyclerView' as managed
type 'MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView'.
I use the latest NuGet packages of Xamarin.Android.Support.. (23.3.0) and MvvmCross (4.1.6 / 4.1.7).
Any idea what causes this exception?
More information now on the issue from Ken Kosmowski:
https://github.com/MvvmCross/MvvmCross-AndroidSupport/issues/252
Use the workaround by #kjeremy referenced there, till the issue got fixed:
"The workaround consists of adding Resources\values\attrs.xml file to your Droid project with the following content:"
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<declare-styleable name="MvxRecyclerView">
<attr name="MvxItemTemplateSelector" format="string" />
</declare-styleable>
</resources>
For completion purpose.
With MVVMCross 4.2.0
You should remove the attrs.xml and change all of your MvxItemTemplateSelector references to MvxTemplateSelector.
I recently split my project and created a library project and a main project. Having a preferences screen that has custom attributes, i removed the preferences with custom attributes from my preferences.xml, put them into their own xml files, included them back into the preferences.xml file and redefined the individual files in the main project (the process is detailed in the answer to another question here.
The project build and run properly. However, I am getting a RuntimeException whenever i try to open the preferences screen. Removing the prefs with custom attrs fixes the problem, so i have traced it back to there. Unfortunately there is no useful information in the exception.
attrs.xml (exists in lib project)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="numberpickerPref">
<attr name="maxValue" format="integer" />
<attr name="minValue" format="integer" />
</declare-styleable>
</resources>
preferences.xml (also in lib project)
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="#string/pref_VibrationSettingsTitle">
<CheckBoxPreference android:key="#string/pref_vibrateFlagKey"
android:title="#string/pref_VibrateTitle"
android:summary="#string/pref_VibrateSummary"
android:defaultValue="false" />
<include layout="#layout/pref_vibrate_on" />
<include layout="#layout/pref_vibrate_off" />
</PreferenceCategory>
</PreferenceScreen>
pref_vibrate_off.xml (defined in both lib and main projects) (only diff is the my namespace, one points to the lib, the other the main project)
<?xml version="1.0" encoding="utf-8"?>
<!-- Stupid workaround because Android still has a bug where custom attributes in a library cause the executable project
problems when building:
https://stackoverflow.com/questions/4461407/help-with-a-custom-view-attributes-inside-a-android-library-project -->
<com.me.numberpicker.NumberPickerPreference
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res/com.me.myapp.lib"
android:key="#string/pref_vibrateOffPeriodKey"
android:title="#string/pref_VibrateOffTitle"
android:summary="#string/pref_VibrateOffSummary"
my:maxValue="#string/MaxVibratorOffPeriodInS"
my:minValue="#string/MinVibratorOffPeriodInS"
android:defaultValue="#string/DefaultVibratorOffPeriodInS" />
MyPreferencesActivity.java
public class MegalarmPreferencesActivity extends PreferenceActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
All the strings are properly defined in the lib project.
If i'm missing anything, let me know please. The preferences were working fine until i split up my project into a lib and main.
Many thanks!
Sean
PreferenceActivity.onCreate can throw RuntimeExceptions internally that the IDE might catch (if configured to do so), but they are also caught internally. For instance, a missing layout_width tag in the default theme seems to cause an exception.
If the RuntimeException is not percolating back to your code don't worry about it. If it is, could you update your question to include the exception message and stack trace?
I would like to know whether there is a way to insert/inject a <string> element defined in an XML file into another <string> element, doing that just with XML.
For example I could have:
<string name="author">Francesco</string>`
and I am looking for something like:
<string name="about_application">Author: #string/author</string>`
so that getString(R.string.about_application) would result in "Author: Francesco".
I know that I could combine the two elements in Java code using String.format(string, formatArgs)like for example:
<string name="author">Francesco</string>
<string name="about_application">Author: %1$s</string>`
and then in code use
String.format(getString(R.string.about_application), getString(R.string.author))
but I would like to do it in XML directly.
Can anyone suggest me a way to do it?
If I understand what you are looking to do, then internal (parsed) general entities might help you achieve what you are looking for.
An example of how you can define the value "Francesco" as an entity called "auth" and then use it in your XML:
<?xml version="1.0"?>
<!DOCTYPE doc [
<!ENTITY auth "Francesco">
]>
<doc>
<string name="author">&auth;</string>
<string name="about_application">Author: &auth;</string>
</doc>
When read by an XML parser, the document will be parsed and evaluated, or "seen", as:
<?xml version="1.0"?>
<doc>
<string name="author">Francesco</string>
<string name="about_application">Author: Francesco</string>
</doc>
Unfortunately I don't think that is possible. I asked a similar question a while ago, and was told it wasn't possible.
Gradle plugin 0.10 brings what they call manifestPlaceholders which basically does what you need but this feature currently only work in the AndroidManifest. There is although an issue opened targeting the next Android build version 1.4 (1.3 is currently in beta4 so should be near RC1 and could see a 1.4 beta1 soon hopefully).
This issue should expand the placeholders in xml configurations files (I just pray this will include strings file and not only basic xml configuration).
From: http://tools.android.com/tech-docs/new-build-system
For custom placeholders replacements, use the following DSL to
configure the placeholders values :
android {
defaultConfig {
manifestPlaceholders = [ activityLabel:"defaultName"]
}
productFlavors {
free {
}
pro {
manifestPlaceholders = [ activityLabel:"proName" ]
}
}
will substitute the placeholder in the following declaration :
<activity android:name=".MainActivity"> android:label="${activityLabel}" >
Can't wait to try it out. This way you could put a placeholder in multiple occurence in the strings file and define the value only in one place instead of modifying all java files to add an argument with %1$s
For now the only clean solution is although the entity trick but this will not work if you want to override the value in flavors since the entity must be defined in the same xml file.
Yes it is possible, I've created this small library that allows you to resolve these placeholders at buildtime, so you won't have to add any Java/Kotlin code to make it work.
Based on your example, you'd have to set up your string like this:
<string name="author">Francesco</string>
<string name="about_application">Author: ${author}</string>
And then the plugin will take care of creating the following:
<!-- Auto generated during compilation -->
<string name="about_application">Author: Francesco</string>
More info here: https://github.com/LikeTheSalad/android-stem