The library is forked from Google’s Guava, which has an EventBus class; Square’s take on the
EventBus
is simply called Bus
, and is optimized for Android. Quoted from the official documentation:"Unlike the Guava event bus, Otto will not traverse the class hierarchy and add methods from base classes or interfaces that are annotated. This is an explicit design decision to improve performance of the library as well as keep your code simple and unambiguous".
Otto is a great way to communicate between your activity and fragments or to communicate between an activity and a service. In this post, I will present a simple project to "listening" the network state changed by
BroadcastReceiver
and update to UI thread through Otto instance.
This post is part of a series called Android TOP useful libraries
Importing library
app/build.gradle
or download jar file from Otto official page:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.squareup:otto:1.3.8' //otto dependency
}
Setup Otto in code
Application
and declaring an Otto instance like this:
MyApplication.java
package info.devexchanges.otto;
import android.app.Application;
import com.squareup.otto.Bus;
import com.squareup.otto.ThreadEnforcer;
public class MyApplication extends Application {
private static Bus eventBus;
public static Bus getInstance() {
return eventBus;
}
@Override
public void onCreate() {
super.onCreate();
eventBus = new Bus(ThreadEnforcer.ANY);
}
}
As you can see at onCreate()
, the Otto instance will be created after call:
eventBus = new Bus(ThreadEnforcer.ANY);
In this example the ThreadEnforcer.ANY
parameter is used, in this case Otto enforces that events will be able to send events from any thread. If you want to send events only from the main thread, use the ThreadEnforcer.MAIN
parameter instead.Sending events with Otto
BroadcastReceiver
to detect the network state changed. In this class, sending event through Otto by post()
method:
InternetBroadcastReceiver.java
package info.devexchanges.otto;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class InternetBroadcastReceiver extends BroadcastReceiver {
@SuppressLint("SimpleDateFormat")
@Override
public void onReceive(Context context, Intent intent) {
String status;
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork == null) {
status = "DISCONNECTED";
} else if (activeNetwork.isConnected()) {
status = "CONNECTED";
} else if (activeNetwork.isConnectedOrConnecting()) {
status = "CONNECTING";
} else status = "";
Log.d("Broadcast", "status: " + status);
// Get current time
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy:HH:mm:ss");
String formattedDate = df.format(c.getTime());
String eventData = "@" + formattedDate + ": device network state: " + status;
// Post the event with this line
MyApplication.getInstance().post(new TransferData(eventData));
}
}
Register and unregister for events
Activities
or Fragments
. Event registration is done via the @Subcribe
annotation on a public single parameter method. The method parameter is the event key, i.e., if such an data type is send via the Otto event bus the method is called.Event receivers must register via the
register()
method of the Bus
class.In this sample project, receiving
Activity
code simple like this:
MainActivity.java
package info.devexchanges.otto;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import com.squareup.otto.Subscribe;
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver broadcastReceiver;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text_view);
MyApplication.getInstance().register(this);
}
@Override
protected void onStop() {
super.onStop();
unregisterReceiver(broadcastReceiver);
}
@Override
protected void onDestroy() {
super.onDestroy();
MyApplication.getInstance().unregister(this);
}
@Override
protected void onResume() {
super.onResume();
broadcastReceiver = new InternetBroadcastReceiver();
registerReceiver(broadcastReceiver, new IntentFilter());
}
@SuppressLint("SetTextI18n")
@Subscribe
public void getMessage(TransferData data) {
Log.i("Activity", data.getMessage());
textView.setText(textView.getText().toString() + "\n" + data.getMessage());
}
}
NOTE
: Never forget to registering your BroadcastReceiver
in AndroidManifest.xml
and provide checking network state permission for your app:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.devexchanges.otto">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:name=".MyApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".InternetBroadcastReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
</manifest>
Recommended transferring data type
Object
use for this project:
TransferData.java
After running app, you will have result like this (when your connection state is changed):package info.devexchanges.otto;
public class TransferData {
private String message;
public TransferData(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
Final thoughts
@Produce
annotation, configuation in proguard-project.txt
file...). Finally, you can take full code of my project on @Github.