java svet - communication between android app components

57
Communication Between Android Application Components Aleksandar Ilić March 20, 2014 @aleksandar_ilic linkedin.com/in/ailic

Upload: aleksandar-ilic

Post on 15-Jan-2015

777 views

Category:

Technology


2 download

DESCRIPTION

Presentation about how to build flexible (using fragments), smooth (using async tasks and intent services) and "data up to date" (using loaders) Android applications.

TRANSCRIPT

Page 1: Java Svet - Communication Between Android App Components

Communication Between

Android Application

Components

Aleksandar Ilić

March 20, 2014

@aleksandar_ilic

linkedin.com/in/ailic

Page 2: Java Svet - Communication Between Android App Components

How to be flexible?

Encapsulate atomic portions

of application’s user interface

or behavior.

Page 3: Java Svet - Communication Between Android App Components

Fragments

Page 4: Java Svet - Communication Between Android App Components

What is a Fragment?

Page 5: Java Svet - Communication Between Android App Components

res/layout/contacts_activity.xml <FrameLayout> <fragment android:name="rs.pstech.android.ContactsList“ android:id="@+id/contacts_list" android:layout_width="match_parent" android:layout_height="match_parent“ /> </FrameLayout>

res/layout-sw800dp/contacts_activity.xml <LinearLayout> <fragment android:name="rs.pstech.android.ContactsList“ android:id="@+id/contacts_list" android:layout_weight="0.30" android:layout_width="0dp" android:layout_height="match_parent“ /> <fragment android:name="rs.pstech.android.ContactDetail“ android:id="@+id/contact_details"

android:layout_weight="0.70" android:layout_width="0dp" android:layout_height="match_parent“ /> </LinearLayout>

Fragments creation

Page 6: Java Svet - Communication Between Android App Components

Fragments creation

Page 7: Java Svet - Communication Between Android App Components

public class ContactsList extends ListFragment {

/** Key to find the data uri in a bundle. */ private static String ARG_DATA_URI = "ArgDataUri"; private Uri mDataUri;

public ContactsList() { // Do NOT use constructors }

public static ContactsList newInstance(Uri uri) { Bundle args = new Bundle(); args.putParcelable(ARG_DATA_URI, uri); ContactsList fragment = new ContactsList(); fragment.setArgments(args); return fragment; }

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDataUri = getArguments().getParcelable(ARG_DATA_URI); } }

Fragments creation

Page 8: Java Svet - Communication Between Android App Components

Communication with activities

Page 9: Java Svet - Communication Between Android App Components

public class ContactsList extends ListFragment implements AdapterView.OnItemClickListener {

// Container Activity must implement this interface public interface OnContactsActionListener { void onViewContactAction(Uri contactUri); }

private OnContactsActionListener mCallback;

@Override public void onAttach(Activity activity) { super.onAttach(context); try { mCallback = (OnContactsActionListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnContactsActionListener"); } }

}

Communication with activities

Page 10: Java Svet - Communication Between Android App Components

public class ContactsActivity extends FragmentActivity implements OnContactsActionListener { ::: @Override public void onViewContactAction(Uri contactUri) { ContactDetail contactDetailFragment = (ContactDetail) getFragmentManager().findFragmentById(R.id.contact_detail); if (contactDetailFragment != null) { // If contact detail is available we are in two-pane layout // Update contact detail’s data contactDetailsFragment.loadData(contactUri); } else { // Otherwise we are in one-pane layout // Start activity to view the contact startActivity(new Intent(Intent.ACTION_VIEW, contactUri)); } } }

Communication with activities

Page 11: Java Svet - Communication Between Android App Components

Communication with fragments

Page 12: Java Svet - Communication Between Android App Components

Communication with fragments

Page 13: Java Svet - Communication Between Android App Components

public class BackupAccountDialog extends DialogFragment {

public interface OnAccountSelectedListener { void onAccountSelected(Account account); } public OnAccountSelectedListener mCallback;

@Override public void onAttach(Activity activity) { super.onAttach(activity); if (getTargetFragment() instanceof OnAccountSelectedListener) { mCallback = (OnAccountSelectedListener) getTargetFragment(); } else if (getParentFragment() instanceof OnAccountSelectedListener) { mCallback = (OnAccountSelectedListener) getParentFragment(); } else { if (activity instanceof OnAccountSelectedListener) { mCallback = (OnAccountSelectedListener) activity; } else { throw new RuntimeExcpetion("What now?"); } } } }

Communication with fragments

Page 14: Java Svet - Communication Between Android App Components

public class ContactsList extends Fragment implements OnAccountSelectedListener { ::: private void showSelectBackupAccount() { BackupAccountDialog dialog = BackupAccountDialog.newInstance(); dialog.setTargetFragment(this, 0); dialog.show(getFragmentManager(), "selectBackupAccountDialog"); } @Override public void onAccountSelected(Account account) { // Do something when account is selected } }

Communication with fragments

Page 15: Java Svet - Communication Between Android App Components

How to be smooth?

Offload long-running operations

from Main UI thread.

Page 16: Java Svet - Communication Between Android App Components

Threads

Page 17: Java Svet - Communication Between Android App Components

Main Thread

• In charge of dispatching events (incl. drawing events)

to user interface widgets.

Page 18: Java Svet - Communication Between Android App Components

Main Thread

• In charge of dispatching events (incl. drawing events)

to user interface widgets.

• All components that run in the same process are

instantiated in the Main (UI) thread.

Page 19: Java Svet - Communication Between Android App Components

Main Thread

• In charge of dispatching events (incl. drawing events)

to user interface widgets.

• All components that run in the same process are

instantiated in the Main (UI) thread.

• Android UI toolkit (components from the android.widget

and android.view packages) is not thread-safe.

Page 20: Java Svet - Communication Between Android App Components

Main Thread Rules

Do not block the Main thread.

Do not access the Android toolkit

from outside the Main thread.

Page 21: Java Svet - Communication Between Android App Components

Accessing Main Thread

• Activity.runOnUiThread(Runnable)

• View.post(Runnable)

• View.postDelayed(Runnable, long)

Page 22: Java Svet - Communication Between Android App Components

public void onClick(View v) { @Override new Thread(new Runnable() { public void run() { final Bitmap bitmap = downloadImage("http://pstech.rs/logo.png"); mImageView.post(new Runnable() { @Override public void run() { mImageView.setImageBitmap(bitmap); } }); } }).start(); }

Worker Thread - Example

Page 23: Java Svet - Communication Between Android App Components

Handlers

Page 24: Java Svet - Communication Between Android App Components

What is an Async Task?

• Designed to be helper class around Thread and Handler.

Page 25: Java Svet - Communication Between Android App Components

What is an Async Task?

• Designed to be helper class around Thread and Handler.

• Ideally to be used for short operations (a few seconds at

the most).

Page 26: Java Svet - Communication Between Android App Components

What is an Async Task?

• Designed to be helper class around Thread and Handler.

• Ideally to be used for short operations (a few seconds at

the most).

• Defined by 3 generic types: Params, Progress and

Result and 4 steps: onPreExecute, doInBackground,

onProgressUpdate and onPostExecute.

Page 27: Java Svet - Communication Between Android App Components

Async Task – Handling configuration changes

Page 28: Java Svet - Communication Between Android App Components

Async Task – Handling configuration changes

Page 29: Java Svet - Communication Between Android App Components

Services

Page 30: Java Svet - Communication Between Android App Components

What is not a Service?

Page 31: Java Svet - Communication Between Android App Components

Why Service?

• A service can run in the background to perform work

even while the user is in a different application.

Page 32: Java Svet - Communication Between Android App Components

Why Service?

• A service can run in the background to perform work

even while the user is in a different application.

• A service can allow other components to bind to it, in

order to interact with it and perform interprocess

communication.

Page 33: Java Svet - Communication Between Android App Components

Intent Service

Page 34: Java Svet - Communication Between Android App Components

public class ContactEditorActivity extends FragmentActivity { ::: private void saveContact() { Intent saveAction = ContactSaveService.createSaveContactIntent(…); startService(saveAction); } ::: }

IntentService usage

Page 35: Java Svet - Communication Between Android App Components

public class ContactSaveService extends IntentService {

private static final String ACTION_SAVE_CONTACT = "saveContact"; private static final String ACTION_DELETE_CONTACT = "deleteContact";

@Override protected void onHandleIntent(Intent intent) { String action = intent.getAction(); if (ACTION_SAVE_CONTACT.equals(action)) { doSaveContact(intent); } else if (ACTION_DELETE_CONTACT.equals(action) { doDeleteContact(intent); } }

public static Intent createSaveContactIntent(Context context, …) { Intent serviceIntent = new Intent(context, ContactSaveService.class); serviceIntent.putExtra(…, …); return serviceIntent; }

::: }

IntentService creation

Page 36: Java Svet - Communication Between Android App Components

What about callbacks?

Page 37: Java Svet - Communication Between Android App Components

What about callbacks?

Result Receiver

Broadcast Receiver

Page 38: Java Svet - Communication Between Android App Components

What is a Result Receiver?

• Generic interface for receiving a callback result from

someone.

Page 39: Java Svet - Communication Between Android App Components

public class ContactEditorActivity extends FragmentActivity { ::: private void saveContact() { Intent saveAction = ContactSaveService.createSaveContactIntent( getActivity(), mOnSaveContactCallback, …); startService(saveAction); } ResultReceiver mOnSaveContactCallback = new ResultReceiver(mHandler) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { // Do something when contact is saved. // On a thread associated with given mHandler. } }; ::: }

Result Receiver – Client side

Page 40: Java Svet - Communication Between Android App Components

public class ContactSaveService extends IntentService {

private static final String EXTRA_CALLBACK = "extraCallback";

public static Intent createSaveContactIntent(Context context, ResultReceiver resultReceiver, …) { Intent serviceIntent = new Intent(context, ContactSaveService.class); serviceIntent.putExtra(EXTRA_CALLBACK, resultReceiver); serviceIntent.putExtra(…, …); return serviceIntent; } private void doSaveContact(Intent intent) { ::: int resultCode = 0; Bundle resultData = new Bundle(); // Result for the listener ResultReceiver callback = intent.getParcelable(EXTRA_CALLBACK); callback.send(resultCode, resultData); } }

Result Receiver – Service side

Page 41: Java Svet - Communication Between Android App Components

What is a Broadcast Receiver?

sendBroadcast() onReceive()

Page 42: Java Svet - Communication Between Android App Components

Broadcast Receiver - Lifecycles

Page 43: Java Svet - Communication Between Android App Components

Local Broadcast Manager

• Helper to register for and send broadcasts of Intents to

local objects within your process.

Page 44: Java Svet - Communication Between Android App Components

Local Broadcast Manager

• Helper to register for and send broadcasts of Intents to

local objects within your process.

Private Secure

Efficient

Page 45: Java Svet - Communication Between Android App Components

Broadcast Receiver – Client side

public class ContactEditorActivity extends FragmentActivity {

protected void onCreate(Bundle savedInstanceState) { LocalBroadcastManager mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); IntentFilter mContactSavedIntentFilter = new IntentFilter(Constants.BROADCAST_CONTACT_SAVED); mLocalBrodcastManager.registerReceiver( mContactSavedReceiver, mContactSavedIntentFilter); }

protected void onDestroy() { mLocalBrodcastManager.unregisterReceiver(mContactSavedReceiver); }

BroadcastReceiver mContactSavedReciver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Do something when contact is saved. } }; }

Page 46: Java Svet - Communication Between Android App Components

Broadcast Receiver – Service side

public class ContactSaveService extends IntentService {

public static Intent createSaveContactIntent(Context context, …) { Intent serviceIntent = new Intent(context, ContactSaveService.class); serviceIntent.putExtra(…, …); return serviceIntent; } private void doSaveContact(Intent intent) { ::: Intent localIntent = new Intent(Constants.BROADCAST_CONTACT_SAVED); localIntent.putExtra(…, …); // Broadcasts the Intent to receivers in this app. LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); } }

Page 47: Java Svet - Communication Between Android App Components

How to be up to date?

Loaders are your friends when

performing asynchronous

loading of data.

Page 48: Java Svet - Communication Between Android App Components

Loaders

Page 49: Java Svet - Communication Between Android App Components

What are Loaders?

API

LoaderManager LoaderManager.LoaderCallbacks

Loader AsyncTaskLoader CursorLoader

Page 50: Java Svet - Communication Between Android App Components

Why Loaders?

• They are available to every Activity and Fragment.

Page 51: Java Svet - Communication Between Android App Components

Why Loaders?

• They are available to every Activity and Fragment.

• They provide asynchronous loading of data.

Page 52: Java Svet - Communication Between Android App Components

Why Loaders?

• They are available to every Activity and Fragment.

• They provide asynchronous loading of data.

• They monitor the source of their data and deliver new

results when the content changes.

Page 53: Java Svet - Communication Between Android App Components

Why Loaders?

• They are available to every Activity and Fragment.

• They provide asynchronous loading of data.

• They monitor the source of their data and deliver new

results when the content changes.

• They automatically reconnect to the last loader's cursor

when being recreated after a configuration change.

Thus, they don't need to re-query their data.

Page 54: Java Svet - Communication Between Android App Components

Using Cursor Loader

public class ContactsList extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {

:::

@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Initializes the loader. It will use the existing one or // create and start a new one. getLoaderManager().initLoader(ID, null /*bundle*/, this /*callbacks*/); } private void setDataUri(Uri dataUri) { mDataUri = dataUri; // Assuming they are not equal getLoaderManager().restartLoader(ID, null, this); } :::

Page 55: Java Svet - Communication Between Android App Components

Using Cursor Loader

:::

@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader(getActivity(), mDataUri, CONTACTS_PROJECITON, null /*selection*/, null /*selArgs*/, Contacts.DISPLAY_NAME); }

@Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Swap the new cursor in. The framework will close the old cursor. mAdapter.swapCursor(data); }

@Override public void onLoaderReset(Loader<Cursor> loader) { // Last cursor is about to be closed. We have to stop using it. mAdapter.swapCursor(null); } }

Page 56: Java Svet - Communication Between Android App Components

• Volite Javu?

• Fokusirani ste na visok kvalitet

koda i optimizaciju performansi?

• Zainteresovani ste za prelazak

na Mobile razvoj?

bit.ly/Java2Android Java2Android

Page 57: Java Svet - Communication Between Android App Components

Thank You!

@aleksandar_ilic

linkedin.com/in/ailic

[email protected]