For example, want to run something in a background thread? Annotate the method with `@Background`. Want to run something in the main/UI thread? (rub some bacon on it) Annotate the method with `@UiThread`.
In this article, I provide a quick walkthrough for creating a very simple Chuck Norris facts app. I'll assume that you already have basic Android knowledge (and using Android Studio + Gradle). Then, at the end, I'll explain in more details some issues/gotchas I ran into while using AndroidAnnotations for the first time, and mention other goodies.
Getting started..
How to add AndroidAnnotations to my project
Using Android Studio + Gradle, the only file you need to edit is your app's `build.gradle`. We will add a dependency for android-apt and some related configurations. The changes to a new project are highlighted:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
def AAVersion = '3.2'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
}
apt {
arguments {
androidManifestFile variant.outputs[0].processResources.manifestFile
resourcePackageName android.defaultConfig.applicationId
}
}
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "net.simplyadvanced.testandroidannotations"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
apt "org.androidannotations:androidannotations:$AAVersion"
compile "org.androidannotations:androidannotations-api:$AAVersion"
}
Now, your project should be ready for adding the annotations and processing them.
- Note: I chose to put the buildscript dependency in the app's build.gradle file so that it only affects the one module. You could also put the android-apt buildscript dependency in your project's root build.gradle so that all sub-projects/modules would be affected.
How to create a very simple Chuck Norris facts app using AndroidAnnotations
This very simple app's feature-set includes: Ability to press a button to download and show a random fact.For simplicity, Strings have not been extracted or made `static final`. And, the code is well-commented to explain each AndroidAnnotations-specific feature introduced.
Here's the following files we are going to edit/add:
- MainActivity.java + activity_main.xml
- MainFragment.java + fragment_main.xml
- AndroidManifest.xml
- HttpUtils.java (has helper method for retrieving text)
In MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// By passing in the layout XML here, we don't need to manually call
// `setContentView()` in `onCreate()`.
@EActivity(R.layout.activity_main)
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Don't add a fragment if onCreate() is called on a config change,
// one already exists.
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
// Note the underscore postfix. AndroidAnnotations works
// by auto-generating a subclass with code that you
// would normally have to write.
.add(R.id.container, new MainFragment_())
.commit();
}
}
}
In /res/layout/activity_main.xml
Nothing special here.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:ignore="MergeRootFrame" />
In MainFragment.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// By passing in layout XML here, we don't need to manually call `onCreateView()`.
@EFragment(R.layout.fragment_main)
public class MainFragment extends Fragment {
// This is the minimum needed to bind a variable to widget in XML.
// AndroidAnnotations will look for an id `R.id.jokeTextView`.
// Or, you could manually specify the id by passing it in as an
// argument to the annotation.
@ViewById TextView jokeTextView;
// Required no-args constructor.
public MainFragment() {}
// This annotation will auto-generate code to find a View with id of
// `R.id.jokeButton` and set the onClickListener to run this method.
@Click
void jokeButtonClicked() {
loadNewJoke();
}
// This annotation makes sure this method is ran in a background thread.
@Background
void loadNewJoke() {
String joke = "N/A";
String jokeJsonString = null;
try {
jokeJsonString = HttpUtils.get("http://api.icndb.com/jokes/random");
JSONObject jokeJson = new JSONObject(jokeJsonString);
if (jokeJson.getString("type").equals("success")) {
joke = jokeJson.getJSONObject("value").getString("joke");
}
} catch (IOException | JSONException | URISyntaxException e) {
e.printStackTrace();
}
setJokeText(joke);
}
// This annotation makes sure this method is ran on the main/UI thread.
@UiThread
void setJokeText(String joke) {
jokeTextView.setText(Html.fromHtml(joke));
}
}
In /res/layout/fragment_main.xml
Nothing special here, except for the ids that will match those in MainFragment.java.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainFragment" >
<Button
android:id="@+id/jokeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Random Joke" />
<TextView
android:id="@+id/jokeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
In AndroidManifest.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.simplyadvanced.testandroidannotations" >
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- Make sure to use the underscore postfix version of MainActivity,
which should be found by the IDE after building. -->
<activity
android:name=".MainActivity_"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
In HttpUtils.java
Nothing special here related to AndroidAnnotations.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Static helper methods related to accessing Internet. */
public class HttpUtils {
/** No need to instantiate this class. */
private HttpUtils() {}
/** Downloads and returns the information from a given URI in the same thread
* this is called in. */
public static String get(String uri) throws IOException, URISyntaxException {
return get(new URI(uri));
}
/** Downloads and returns the information from a given URI in the same
* thread this is called in. The returned String may contain XML, JSON,
* or another format. You should check for network connectivity before
* calling this.
* Note: This is just a simple implementation, it should be made more
* robust, like by using a nice library. */
public static String get(URI uri) throws IOException {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet();
httpGet.setURI(uri);
HttpResponse httpResponse = httpClient.execute(httpGet);
InputStream inputStream;
BufferedReader reader = null;
String value = null;
try {
inputStream = httpResponse.getEntity().getContent();
reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder(inputStream.available());
while ((value = reader.readLine()) != null) {
sb.append(value);
}
value = sb.toString();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// Close quietly.
}
}
}
return value;
}
}
If running this code, then you may want to add a check for Internet availability. And, you can check out the full source code, which has that check and a few more tweaks: https://github.com/danialgoodwin/android-learn/tree/master/sample-apps/framework--android-annotations--chuck-norris
When you build the project, all of the generated code can be found in `/app/build/generated/source/apt/debug`. You'll be able to see exactly what code will be executing during runtime and where any performance issues may be.
There is a bunch more annotations and features available. But, hopefully, this was enough to get you started and slightly interested in learning more. ;)
Gotchas (Things to look out for)
Here's a few issues I ran into while setting up AndroidAnnotations for the first time. Hopefully, it will save others some time.- When navigating to an Activity or Fragment annotated, make sure to navigate to the version with the underscore after it because that's the file with all the auto-generated code.
- I was not able to use an annotated Fragment that was an inner class of an Activity.
Linked Resources:
~ Danial Goodwin ~
ps - By the way, have you heard of LTE Discovery or Simply Advanced Unit Converter?
No comments:
Post a Comment