├── .gitignore
├── EatApplication
├── .gitignore
├── Eat
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.txt
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── ic_launcher-web.png
│ │ ├── java
│ │ └── com
│ │ │ └── eat
│ │ │ ├── StartActivity.java
│ │ │ ├── chapter1
│ │ │ └── Chapter1Activity.java
│ │ │ ├── chapter10
│ │ │ ├── Chapter10Activity.java
│ │ │ └── FileDownloadActivity.java
│ │ │ ├── chapter11
│ │ │ ├── BluetoothActivity.java
│ │ │ ├── BluetoothService.java
│ │ │ ├── BoundLocalActivity.java
│ │ │ ├── BoundLocalActivity2.java
│ │ │ ├── BoundLocalService.java
│ │ │ ├── BoundLocalService2.java
│ │ │ ├── Chapter11Activity.java
│ │ │ ├── DownloadActivity.java
│ │ │ └── DownloadService.java
│ │ │ ├── chapter12
│ │ │ ├── AlarmBroadcastActivity.java
│ │ │ ├── AlarmReceiver.java
│ │ │ ├── Chapter12Activity.java
│ │ │ ├── NetworkCheckerIntentService.java
│ │ │ ├── WebService.java
│ │ │ └── WebServiceActivity.java
│ │ │ ├── chapter13
│ │ │ ├── Chapter13Activity.java
│ │ │ └── ExpandableContactListActivity.java
│ │ │ ├── chapter14
│ │ │ ├── BasicActivity.java
│ │ │ ├── BasicLoader.java
│ │ │ ├── Chapter14Activity.java
│ │ │ ├── ChromeBookmarkActivity.java
│ │ │ ├── ContactActivity.java
│ │ │ ├── EditBookmarkDialog.java
│ │ │ ├── FileActivity.java
│ │ │ ├── FileListFragment.java
│ │ │ └── FileLoader.java
│ │ │ ├── chapter2
│ │ │ └── Chapter2Activity.java
│ │ │ ├── chapter3
│ │ │ └── Chapter3Activity.java
│ │ │ ├── chapter4
│ │ │ ├── Chapter4Activity.java
│ │ │ ├── ConsumeAndQuitThreadActivity.java
│ │ │ ├── HandlerCallbackActivity.java
│ │ │ ├── HandlerExampleActivity.java
│ │ │ ├── LooperActivity.java
│ │ │ ├── MQDebugActivity.java
│ │ │ └── PipeExampleActivity.java
│ │ │ ├── chapter5
│ │ │ ├── Chapter5Activity.java
│ │ │ ├── MessengerOnewayActivity.java
│ │ │ ├── MessengerTwowayActivity.java
│ │ │ └── WorkerThreadService.java
│ │ │ ├── chapter6
│ │ │ └── Chapter6Activity.java
│ │ │ ├── chapter7
│ │ │ ├── Chapter7Activity.java
│ │ │ ├── ThreadFragment.java
│ │ │ ├── ThreadRetainActivity.java
│ │ │ └── ThreadRetainWithFragmentActivity.java
│ │ │ ├── chapter8
│ │ │ ├── ChainedNetworkActivity.java
│ │ │ ├── Chapter8Activity.java
│ │ │ ├── MyHandlerThread.java
│ │ │ └── SharedPreferencesActivity.java
│ │ │ └── chapter9
│ │ │ ├── Chapter9Activity.java
│ │ │ ├── ECSImageDownloaderActivity.java
│ │ │ ├── InvokeActivity.java
│ │ │ ├── LowPriorityThreadFactory.java
│ │ │ ├── PrestartedCores.java
│ │ │ ├── SimpleExecutor.java
│ │ │ └── TaskTrackingThreadPool.java
│ │ └── res
│ │ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── layout
│ │ ├── activity_alarm_broadcast.xml
│ │ ├── activity_basic.xml
│ │ ├── activity_bluetooth.xml
│ │ ├── activity_bookmarks.xml
│ │ ├── activity_bound_local_service_async_client.xml
│ │ ├── activity_bound_local_service_sync_client.xml
│ │ ├── activity_chapter1.xml
│ │ ├── activity_chapter10.xml
│ │ ├── activity_chapter11.xml
│ │ ├── activity_chapter12.xml
│ │ ├── activity_chapter13.xml
│ │ ├── activity_chapter14.xml
│ │ ├── activity_chapter2.xml
│ │ ├── activity_chapter3.xml
│ │ ├── activity_chapter4.xml
│ │ ├── activity_chapter5.xml
│ │ ├── activity_chapter6.xml
│ │ ├── activity_chapter7.xml
│ │ ├── activity_chapter8.xml
│ │ ├── activity_chapter9.xml
│ │ ├── activity_download_service.xml
│ │ ├── activity_ecs_image_downloader.xml
│ │ ├── activity_file.xml
│ │ ├── activity_file_download.xml
│ │ ├── activity_futuretask_preload.xml
│ │ ├── activity_handler_callback.xml
│ │ ├── activity_handler_example.xml
│ │ ├── activity_invoke.xml
│ │ ├── activity_looper.xml
│ │ ├── activity_messenger_client.xml
│ │ ├── activity_mq_debug.xml
│ │ ├── activity_pipe.xml
│ │ ├── activity_retain_thread.xml
│ │ ├── activity_shared_preferences.xml
│ │ ├── activity_start.xml
│ │ ├── activity_web_service.xml
│ │ └── dialog_edit_bookmark.xml
│ │ ├── menu
│ │ └── start.xml
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── dimens.xml
│ │ └── strings.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | bin/
13 | gen/
14 |
15 | # Local configuration file (sdk path, etc)
16 | local.properties
17 |
18 | # Eclipse project files
19 | .classpath
20 | .project
21 |
22 | # Proguard folder generated by Eclipse
23 | proguard/
24 |
25 | # Intellij project files
26 | *.iml
27 | *.ipr
28 | *.iws
29 | .idea/
30 |
--------------------------------------------------------------------------------
/EatApplication/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea/workspace.xml
4 | .DS_Store
5 |
--------------------------------------------------------------------------------
/EatApplication/Eat/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/EatApplication/Eat/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'android'
2 |
3 | android {
4 | compileSdkVersion 19
5 | buildToolsVersion '19.1.0'
6 |
7 | defaultConfig {
8 | minSdkVersion 16
9 | targetSdkVersion 19
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | runProguard false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
17 | }
18 | }
19 | lintOptions {
20 | abortOnError false
21 | }
22 | }
23 |
24 | dependencies {
25 | compile fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
26 | }
27 |
--------------------------------------------------------------------------------
/EatApplication/Eat/proguard-rules.txt:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/andersgoransson/development/android-sdk-macosx/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the ProGuard
5 | # include property in project.properties.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
39 |
40 |
41 |
44 |
45 |
46 |
49 |
50 |
51 |
54 |
57 |
60 |
63 |
66 |
69 |
72 |
73 |
74 |
77 |
80 |
83 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
94 |
95 |
96 |
99 |
102 |
105 |
106 |
107 |
110 |
113 |
116 |
117 |
118 |
121 |
124 |
127 |
128 |
129 |
132 |
135 |
136 |
137 |
140 |
143 |
144 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
156 |
157 |
160 |
161 |
162 |
163 |
166 |
169 |
170 |
173 |
174 |
175 |
176 |
179 |
182 |
183 |
184 |
187 |
190 |
193 |
196 |
199 |
200 |
201 |
202 |
203 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andersgoransson/eatbookexamples/b6476cba9d931982b2f8c07a5fb7c529b3ba73d4/EatApplication/Eat/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/StartActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.chapter10.Chapter10Activity;
9 | import com.eat.chapter11.Chapter11Activity;
10 | import com.eat.chapter12.Chapter12Activity;
11 | import com.eat.chapter13.Chapter13Activity;
12 | import com.eat.chapter14.Chapter14Activity;
13 | import com.eat.chapter4.Chapter4Activity;
14 | import com.eat.chapter5.Chapter5Activity;
15 | import com.eat.chapter6.Chapter6Activity;
16 | import com.eat.chapter7.Chapter7Activity;
17 | import com.eat.chapter8.Chapter8Activity;
18 | import com.eat.chapter9.Chapter9Activity;
19 |
20 | public class StartActivity extends Activity {
21 |
22 | @Override
23 | protected void onCreate(Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | setContentView(R.layout.activity_start);
26 | }
27 |
28 | public void onChapter1(View v) {
29 | // Empty, no examples in this chapter.
30 | }
31 |
32 | public void onChapter2(View v) {
33 | // Empty, no examples in this chapter.
34 | }
35 |
36 | public void onChapter3(View v) {
37 | // Empty, no examples in this chapter.
38 | }
39 |
40 | public void onChapter4(View v) {
41 | startActivity(new Intent(this, Chapter4Activity.class));
42 | }
43 |
44 | public void onChapter5(View v) {
45 | startActivity(new Intent(this, Chapter5Activity.class));
46 | }
47 |
48 | public void onChapter6(View v) {
49 | startActivity(new Intent(this, Chapter6Activity.class));
50 | }
51 |
52 | public void onChapter7(View v) {
53 | startActivity(new Intent(this, Chapter7Activity.class));
54 | }
55 |
56 | public void onChapter8(View v) {
57 | startActivity(new Intent(this, Chapter8Activity.class));
58 | }
59 |
60 | public void onChapter9(View v) {
61 | startActivity(new Intent(this, Chapter9Activity.class));
62 | }
63 |
64 | public void onChapter10(View v) {
65 | startActivity(new Intent(this, Chapter10Activity.class));
66 | }
67 |
68 | public void onChapter11(View v) {
69 | startActivity(new Intent(this, Chapter11Activity.class));
70 | }
71 |
72 | public void onChapter12(View v) {
73 | startActivity(new Intent(this, Chapter12Activity.class));
74 | }
75 |
76 | public void onChapter13(View v) {
77 | startActivity(new Intent(this, Chapter13Activity.class));
78 | }
79 |
80 | public void onChapter14(View v) {
81 | startActivity(new Intent(this, Chapter14Activity.class));
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter1/Chapter1Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter1;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 |
10 | public class Chapter1Activity extends Activity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_chapter1);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter10/Chapter10Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter10;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 |
10 | public class Chapter10Activity extends Activity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_chapter10);
16 | }
17 |
18 | public void onFileDownloadActivity(View v) {
19 | startActivity(new Intent(this, FileDownloadActivity.class));
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter10/FileDownloadActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter10;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.os.AsyncTask;
7 | import android.os.Bundle;
8 | import android.view.View;
9 | import android.widget.ImageView;
10 | import android.widget.LinearLayout;
11 | import android.widget.ProgressBar;
12 |
13 | import com.eat.R;
14 |
15 | import java.io.IOException;
16 | import java.io.InputStream;
17 | import java.net.MalformedURLException;
18 | import java.net.URL;
19 |
20 |
21 | public class FileDownloadActivity extends Activity {
22 |
23 | private static final String[] DOWNLOAD_URLS = {
24 | "http://developer.android.com/design/media/devices_displays_density@2x.png",
25 | "http://developer.android.com/design/media/iconography_launcher_example2.png",
26 | "http://developer.android.com/design/media/iconography_actionbar_focal.png",
27 | "http://developer.android.com/design/media/iconography_actionbar_colors.png"
28 | };
29 |
30 | DownloadTask mFileDownloaderTask;
31 |
32 | // Views from layout file
33 | private ProgressBar mProgressBar;
34 | private LinearLayout mLayoutImages;
35 |
36 | @Override
37 | public void onCreate(Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 |
40 | setContentView(R.layout.activity_file_download);
41 | mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
42 | mProgressBar.setMax(DOWNLOAD_URLS.length);
43 | mLayoutImages = (LinearLayout) findViewById(R.id.layout_images);
44 |
45 | mFileDownloaderTask = new DownloadTask(this);
46 | mFileDownloaderTask.execute(DOWNLOAD_URLS);
47 | }
48 |
49 | @Override
50 | protected void onDestroy() {
51 | super.onDestroy();
52 | mFileDownloaderTask.setActivity(null);
53 | mFileDownloaderTask.cancel(true);
54 | }
55 |
56 | private static class DownloadTask extends AsyncTask {
57 |
58 | private FileDownloadActivity mActivity;
59 | private int mCount = 0;
60 |
61 | public DownloadTask(FileDownloadActivity activity) {
62 | mActivity = activity;
63 | }
64 |
65 | public void setActivity(FileDownloadActivity activity) {
66 | mActivity = activity;
67 | }
68 |
69 | @Override
70 | protected void onPreExecute() {
71 | super.onPreExecute();
72 | mActivity.mProgressBar.setVisibility(View.VISIBLE);
73 | mActivity.mProgressBar.setProgress(0);
74 | }
75 |
76 | @Override
77 | protected Void doInBackground(String... urls) {
78 | for (String url : urls) {
79 | if (!isCancelled()) {
80 | Bitmap bitmap = downloadFile(url);
81 | publishProgress(bitmap);
82 | }
83 | }
84 | return null;
85 | }
86 |
87 |
88 | @Override
89 | protected void onProgressUpdate(Bitmap... bitmaps) {
90 | super.onProgressUpdate(bitmaps);
91 | if (mActivity != null) {
92 | mActivity.mProgressBar.setProgress(++mCount);
93 | ImageView iv = new ImageView(mActivity);
94 | iv.setImageBitmap(bitmaps[0]);
95 | mActivity.mLayoutImages.addView(iv);
96 | }
97 | }
98 |
99 | @Override
100 | protected void onPostExecute(Void aVoid) {
101 | super.onPostExecute(aVoid);
102 | if (mActivity != null) {
103 | mActivity.mProgressBar.setVisibility(View.GONE);
104 | }
105 | }
106 |
107 | @Override
108 | protected void onCancelled() {
109 | super.onCancelled();
110 | if (mActivity != null) {
111 | mActivity.mProgressBar.setVisibility(View.GONE);
112 | }
113 | }
114 |
115 |
116 | private Bitmap downloadFile(String url) {
117 | Bitmap bitmap = null;
118 | try {
119 | bitmap = BitmapFactory
120 | .decodeStream((InputStream) new URL(url)
121 | .getContent());
122 | } catch (MalformedURLException e) {
123 | e.printStackTrace();
124 | } catch (IOException e) {
125 | e.printStackTrace();
126 | }
127 | return bitmap;
128 | }
129 |
130 | }
131 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter11/BluetoothActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter11;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 |
10 |
11 | public class BluetoothActivity extends Activity {
12 | public void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 | setContentView(R.layout.activity_bluetooth);
15 | }
16 |
17 | public void onStartListening(View v) {
18 | Intent intent = new Intent(this, BluetoothService.class);
19 | intent.putExtra(BluetoothService.COMMAND_KEY, BluetoothService.COMMAND_START_LISTENING);
20 | startService(intent);
21 | }
22 |
23 | public void onStopListening(View v) {
24 | Intent intent = new Intent(this, BluetoothService.class);
25 | stopService(intent);
26 | }
27 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter11/BluetoothService.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter11;
2 |
3 | import android.app.Service;
4 | import android.bluetooth.BluetoothAdapter;
5 | import android.bluetooth.BluetoothServerSocket;
6 | import android.bluetooth.BluetoothSocket;
7 | import android.content.Intent;
8 | import android.content.res.Configuration;
9 | import android.os.IBinder;
10 | import android.util.Log;
11 |
12 | import java.io.IOException;
13 | import java.util.UUID;
14 |
15 |
16 | public class BluetoothService extends Service {
17 |
18 | private static final String TAG = "BluetoothService";
19 | public static final String COMMAND_KEY = "command_key";
20 | public static final String COMMAND_START_LISTENING = "command_start_discovery";
21 |
22 | private static final UUID MY_UUID = new UUID(323476234, 34587387);
23 | private static final String SDP_NAME = "custom_sdp_name";
24 |
25 |
26 | private BluetoothAdapter mAdapter;
27 | private BluetoothServerSocket mServerSocket;
28 | private boolean mListening = false;
29 | private Thread listeningThread;
30 |
31 |
32 | public IBinder onBind(Intent intent) {
33 | return null;
34 | }
35 |
36 | @Override
37 | public void onCreate() {
38 | super.onCreate();
39 | mAdapter = BluetoothAdapter.getDefaultAdapter();
40 | }
41 |
42 | @Override
43 | public int onStartCommand(Intent intent, int flags, int startId) {
44 | if (mAdapter != null) {
45 | if (intent.getStringExtra(COMMAND_KEY).equals(COMMAND_START_LISTENING) && mListening == false) {
46 | startListening();
47 | }
48 | }
49 | return START_REDELIVER_INTENT;
50 | }
51 |
52 | private void startListening() {
53 | mListening = true;
54 | listeningThread = new Thread(new Runnable() {
55 |
56 | @Override
57 | public void run() {
58 | BluetoothSocket socket = null;
59 | try {
60 | mServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord(SDP_NAME, MY_UUID);
61 | socket = mServerSocket.accept();
62 |
63 | if (socket != null) {
64 | // Handle BT connection
65 | }
66 |
67 | } catch (IOException e) {
68 | Log.d(TAG, "Server socket closed");
69 | }
70 | }
71 | });
72 | listeningThread.start();
73 | }
74 |
75 | private void stopListening() {
76 | mListening = false;
77 | try {
78 | if (mServerSocket != null) {
79 | mServerSocket.close();
80 | }
81 | } catch (IOException e) {
82 | e.printStackTrace();
83 | }
84 | }
85 |
86 | @Override
87 | public void onDestroy() {
88 | super.onDestroy();
89 | stopListening();
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter11/BoundLocalActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter11;
2 |
3 | import android.app.Activity;
4 | import android.app.Service;
5 | import android.content.ComponentName;
6 | import android.content.Intent;
7 | import android.content.ServiceConnection;
8 | import android.os.Bundle;
9 | import android.os.IBinder;
10 | import android.view.View;
11 | import android.widget.TextView;
12 |
13 | import com.eat.R;
14 |
15 | import java.lang.ref.WeakReference;
16 |
17 |
18 | public class BoundLocalActivity extends Activity {
19 |
20 | private LocalServiceConnection mLocalServiceConnection = new LocalServiceConnection();
21 | private BoundLocalService mBoundLocalService;
22 | private boolean mIsBound;
23 |
24 | public void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | bindService(new Intent(BoundLocalActivity.this, BoundLocalService.class),
27 | mLocalServiceConnection,
28 | Service.BIND_AUTO_CREATE);
29 | mIsBound = true;
30 | }
31 | @Override
32 | protected void onDestroy() { super.onDestroy();
33 | if (mIsBound) {
34 | try {
35 | unbindService(mLocalServiceConnection);
36 | mIsBound = false;
37 | } catch (IllegalArgumentException e) {
38 | // No bound service
39 | }
40 | }
41 | }
42 | private class LocalServiceConnection implements ServiceConnection {
43 | @Override
44 | public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
45 | mBoundLocalService = ((BoundLocalService.ServiceBinder)iBinder).getService();
46 |
47 | // At this point clients can invoke methods in the Service,
48 | // i.e. publishedMethod1 and publishedMethod2.
49 | }
50 |
51 | @Override
52 | public void onServiceDisconnected(ComponentName componentName) {
53 | mBoundLocalService = null;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter11/BoundLocalActivity2.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter11;
2 |
3 | import android.app.Activity;
4 | import android.app.Service;
5 | import android.content.ComponentName;
6 | import android.content.Intent;
7 | import android.content.ServiceConnection;
8 | import android.os.Bundle;
9 | import android.os.IBinder;
10 | import android.view.View;
11 | import android.widget.TextView;
12 |
13 | import com.eat.R;
14 |
15 | import java.lang.ref.WeakReference;
16 |
17 |
18 | public class BoundLocalActivity2 extends Activity {
19 |
20 | private TextView tvStatus;
21 |
22 | private LocalServiceConnection mLocalServiceConnection = new LocalServiceConnection();
23 | private boolean mIsBound;
24 | private BoundLocalService2 mBoundLocalService;
25 |
26 | private static class ServiceListener implements BoundLocalService2.OperationListener {
27 |
28 | private WeakReference mWeakActivity;
29 |
30 | public ServiceListener(BoundLocalActivity2 activity) {
31 | this.mWeakActivity = new WeakReference(activity);
32 | }
33 |
34 | @Override
35 | public void onOperationDone(final int someResult) {
36 | final BoundLocalActivity2 localReferenceActivity = mWeakActivity.get();
37 | if (localReferenceActivity != null) {
38 | localReferenceActivity.runOnUiThread(new Runnable(){
39 | @Override
40 | public void run() {
41 | localReferenceActivity.tvStatus.setText(Integer.toString(someResult));
42 | }
43 | });
44 | }
45 | }
46 | }
47 |
48 | public void onCreate(Bundle savedInstanceState) {
49 | super.onCreate(savedInstanceState);
50 | setContentView(R.layout.activity_bound_local_service_sync_client);
51 | tvStatus = (TextView) findViewById(R.id.text_status);
52 |
53 | bindService(new Intent(BoundLocalActivity2.this, BoundLocalService2.class), mLocalServiceConnection, Service.BIND_AUTO_CREATE);
54 | mIsBound = true;
55 | }
56 |
57 | @Override
58 | protected void onDestroy() {
59 | super.onDestroy();
60 | if (mIsBound) {
61 | try {
62 | unbindService(mLocalServiceConnection);
63 | mIsBound = false;
64 | } catch (IllegalArgumentException e) {
65 | // No bound service
66 | }
67 | }
68 | }
69 |
70 |
71 | public void onClickExecuteOnClientUIThread(View v) {
72 | if (mBoundLocalService != null) {
73 | mBoundLocalService.doLongAsyncOperation(new ServiceListener(this));
74 | }
75 | }
76 |
77 | private class LocalServiceConnection implements ServiceConnection {
78 |
79 | @Override
80 | public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
81 | mBoundLocalService = ((BoundLocalService2.ServiceBinder)iBinder).getService();
82 | }
83 |
84 | @Override
85 | public void onServiceDisconnected(ComponentName componentName) {
86 | mBoundLocalService = null;
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter11/BoundLocalService.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter11;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.os.Binder;
6 | import android.os.IBinder;
7 | import android.util.Log;
8 |
9 |
10 | public class BoundLocalService extends Service {
11 |
12 | private final ServiceBinder mBinder = new ServiceBinder();
13 |
14 | public IBinder onBind(Intent intent) {
15 | return mBinder;
16 | }
17 |
18 | public class ServiceBinder extends Binder {
19 | public BoundLocalService getService() {
20 | return BoundLocalService.this;
21 | }
22 | }
23 |
24 | // Methods published to clients.
25 | public void publishedMethod1() { /* TO IMPLEMENT */ }
26 |
27 | public void publishedMethod2() { /* TO IMPLEMENT */ }
28 | }
29 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter11/BoundLocalService2.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter11;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.content.res.Configuration;
6 | import android.os.Binder;
7 | import android.os.IBinder;
8 | import android.os.SystemClock;
9 | import android.util.Log;
10 |
11 | import java.util.concurrent.Executor;
12 |
13 |
14 | public class BoundLocalService2 extends Service {
15 |
16 | private final ServiceBinder mBinder = new ServiceBinder();
17 | private final TaskExecutor executor = new TaskExecutor();
18 |
19 | public interface OperationListener {
20 | public void onOperationDone(int i);
21 | }
22 |
23 | public IBinder onBind(Intent intent) {
24 | return mBinder;
25 | }
26 |
27 | @Override
28 | public void onCreate() {
29 | super.onCreate();
30 |
31 | }
32 |
33 | public class ServiceBinder extends Binder {
34 | public BoundLocalService2 getService() {
35 | return BoundLocalService2.this;
36 | }
37 | }
38 |
39 |
40 | public int doLongSyncOperation() {
41 | return longOperation();
42 | }
43 |
44 | public void doLongAsyncOperation(final OperationListener listener) {
45 | executor.execute(new Runnable() {
46 | @Override
47 | public void run() {
48 | int result = longOperation();
49 | listener.onOperationDone(result);
50 | }
51 | });
52 | }
53 |
54 | private int longOperation() {
55 | SystemClock.sleep(10000);
56 | return 42;
57 | }
58 |
59 | public class TaskExecutor implements Executor {
60 | @Override
61 | public void execute(Runnable runnable) {
62 | new Thread(runnable).start();
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter11/Chapter11Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter11;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 | import com.eat.chapter10.FileDownloadActivity;
10 |
11 | public class Chapter11Activity extends Activity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_chapter11);
17 | }
18 |
19 | public void onBluetoothActivity(View v) {
20 | startActivity(new Intent(this, BluetoothActivity.class));
21 | }
22 |
23 | public void onDownloadActivity(View v) {
24 | startActivity(new Intent(this, DownloadActivity.class));
25 | }
26 |
27 | public void onBoundLocalActivity(View v) {
28 | startActivity(new Intent(this, BoundLocalActivity.class));
29 | }
30 |
31 | public void onBoundLocalActivity2(View v) {
32 | startActivity(new Intent(this, BoundLocalActivity2.class));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter11/DownloadActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter11;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.Bundle;
7 | import android.util.Log;
8 | import android.view.View;
9 |
10 | import com.eat.R;
11 |
12 |
13 | public class DownloadActivity extends Activity {
14 |
15 | private static final String DOWNLOAD_URL = "http://developer.android.com/design/media/devices_displays_density@2x.png";
16 |
17 |
18 | public void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_download_service);
21 | }
22 |
23 | public void onStartDownload(View v) {
24 | Intent intent = new Intent("com.eat.ACTION_DOWNLOAD");
25 | intent.setData(Uri.parse(DOWNLOAD_URL));
26 | startService(intent);
27 | }
28 |
29 | public void onStopService(View v) {
30 | Intent intent = new Intent(this, DownloadService.class);
31 | stopService(intent);
32 | }
33 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter11/DownloadService.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter11;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.IBinder;
7 | import android.os.SystemClock;
8 | import android.util.Log;
9 |
10 | import java.util.concurrent.ExecutorService;
11 | import java.util.concurrent.Executors;
12 |
13 |
14 | public class DownloadService extends Service {
15 |
16 | private ExecutorService mDownloadExecutor;
17 | private int mCommandCount;
18 |
19 | public IBinder onBind(Intent intent) {
20 | return null;
21 | }
22 |
23 | @Override
24 | public void onCreate() {
25 | super.onCreate();
26 | mDownloadExecutor = Executors.newFixedThreadPool(4);
27 | }
28 |
29 | @Override
30 | public void onDestroy() {
31 | super.onDestroy();
32 | mDownloadExecutor.shutdownNow();
33 | }
34 |
35 | @Override
36 | public int onStartCommand(Intent intent, int flags, int startId) {
37 | synchronized (this) {
38 | mCommandCount++;
39 | }
40 | if (intent != null) {
41 | downloadFile(intent.getData());
42 | }
43 | return START_REDELIVER_INTENT;
44 | }
45 |
46 | private void downloadFile(final Uri uri) {
47 | mDownloadExecutor.submit(new Runnable() {
48 | @Override
49 | public void run() {
50 |
51 | // Simulate long file download
52 | SystemClock.sleep(10000);
53 |
54 | synchronized (this) {
55 | if (--mCommandCount <= 0) {
56 | stopSelf();
57 | }
58 | }
59 | }
60 | });
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter12/AlarmBroadcastActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter12;
2 |
3 | import android.app.Activity;
4 | import android.app.AlarmManager;
5 | import android.app.PendingIntent;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.content.IntentFilter;
9 | import android.os.Bundle;
10 | import android.os.SystemClock;
11 | import android.widget.TextView;
12 |
13 | import com.eat.R;
14 |
15 |
16 | public class AlarmBroadcastActivity extends Activity {
17 |
18 | private static final long ONE_HOUR = 60 * 60 * 1000;
19 | TextView tvStatus;
20 |
21 | AlarmManager am;
22 |
23 | AlarmReceiver alarmReceiver;
24 |
25 | public void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_alarm_broadcast);
28 | tvStatus = (TextView) findViewById(R.id.text_alarm_status);
29 |
30 | alarmReceiver = new AlarmReceiver();
31 | registerReceiver(alarmReceiver, new IntentFilter("com.eat.alarmreceiver"));
32 |
33 | PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent("com.eat.alarmreceiver"), PendingIntent.FLAG_UPDATE_CURRENT);
34 | am = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
35 | am.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()
36 | + ONE_HOUR, ONE_HOUR, pendingIntent);
37 | tvStatus.setText("Alarm is set");
38 | }
39 |
40 | @Override
41 | protected void onDestroy() {
42 | super.onDestroy();
43 | unregisterReceiver(alarmReceiver);
44 | }
45 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter12/AlarmReceiver.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter12;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 |
7 | public class AlarmReceiver extends BroadcastReceiver {
8 |
9 | public void onReceive(Context context, Intent intent) {
10 | context.startService(new Intent(context, NetworkCheckerIntentService.class));
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter12/Chapter12Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter12;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 | import com.eat.chapter11.BoundLocalActivity;
10 | import com.eat.chapter11.BoundLocalActivity2;
11 |
12 | public class Chapter12Activity extends Activity {
13 |
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.activity_chapter12);
18 | }
19 |
20 | public void onAlarmBroadcastActivity(View v) {
21 | startActivity(new Intent(this, AlarmBroadcastActivity.class));
22 | }
23 |
24 | public void onWebServiceActivity(View v) {
25 | startActivity(new Intent(this, WebServiceActivity.class));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter12/NetworkCheckerIntentService.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter12;
2 |
3 | import android.app.IntentService;
4 | import android.app.Notification;
5 | import android.app.NotificationManager;
6 | import android.content.Context;
7 | import android.content.Intent;
8 |
9 | import com.eat.R;
10 |
11 |
12 | public class NetworkCheckerIntentService extends IntentService {
13 |
14 | public NetworkCheckerIntentService() {
15 | super("NetworkCheckerThread");
16 | }
17 |
18 | @Override
19 | protected void onHandleIntent(Intent intent) {
20 | if (isNewNetworkDataAvailable()) {
21 | addStatusBarNotification();
22 | }
23 | }
24 |
25 | private boolean isNewNetworkDataAvailable() {
26 | // Network request code omitted. Returns dummy result.
27 | return true;
28 | }
29 |
30 | private void addStatusBarNotification() {
31 | Notification.Builder mBuilder =
32 | new Notification.Builder(this)
33 | .setSmallIcon(R.drawable.ic_launcher)
34 | .setContentTitle("New network data")
35 | .setContentText("New data can be downloaded.");
36 |
37 | NotificationManager mNotificationManager =
38 | (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
39 | mNotificationManager.notify(1, mBuilder.build());
40 | }
41 |
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter12/WebService.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter12;
2 |
3 | import java.io.IOException;
4 | import java.net.URI;
5 | import java.net.URISyntaxException;
6 |
7 | import org.apache.http.HttpEntity;
8 | import org.apache.http.HttpResponse;
9 | import org.apache.http.StatusLine;
10 | import org.apache.http.client.HttpClient;
11 | import org.apache.http.client.methods.HttpGet;
12 | import org.apache.http.client.methods.HttpPost;
13 | import org.apache.http.client.methods.HttpRequestBase;
14 | import org.apache.http.entity.StringEntity;
15 | import org.apache.http.impl.client.DefaultHttpClient;
16 | import org.apache.http.util.EntityUtils;
17 |
18 | import android.app.IntentService;
19 | import android.content.Intent;
20 | import android.net.Uri;
21 | import android.os.Bundle;
22 | import android.os.ResultReceiver;
23 |
24 | public class WebService extends IntentService {
25 | private static final String TAG = WebService.class.getName();
26 | public static final int GET = 1;
27 | public static final int POST = 2;
28 |
29 | public static final String INTENT_KEY_REQUEST_TYPE = "com.eat.INTENT_KEY_REQUEST_TYPE";
30 | public static final String INTENT_KEY_JSON = "com.eat.INTENT_KEY_JSON";
31 | public static final String INTENT_KEY_RECEIVER = "com.eat.INTENT_KEY_RECEIVER";
32 | public static final String BUNDLE_KEY_REQUEST_RESULT = "com.eat.BUNDLE_KEY_REQUEST_RESULT";
33 |
34 | public WebService() {
35 | super(TAG);
36 | }
37 |
38 | @Override
39 | protected void onHandleIntent(Intent intent) {
40 |
41 | Uri uri = intent.getData();
42 | int requestType = intent.getIntExtra(INTENT_KEY_REQUEST_TYPE, 0);
43 | String json = (String)intent.getSerializableExtra(INTENT_KEY_JSON);
44 | ResultReceiver receiver = intent.getParcelableExtra(INTENT_KEY_RECEIVER);
45 |
46 | try {
47 | HttpRequestBase request = null;
48 | switch (requestType) {
49 | case GET: {
50 | request = new HttpGet();
51 | // Request setup omitted
52 | break;
53 | }
54 | case POST: {
55 | request = new HttpPost();
56 | if (json != null) {
57 | ((HttpPost)request).setEntity(new StringEntity(json));
58 | }
59 | // Request setup omitted
60 | break;
61 | }
62 | }
63 |
64 | if (request != null) {
65 | request.setURI(new URI(uri.toString()));
66 | HttpResponse response = doRequest(request);
67 | HttpEntity httpEntity = response.getEntity();
68 | StatusLine responseStatus = response.getStatusLine();
69 | int statusCode = responseStatus != null ? responseStatus.getStatusCode() : 0;
70 |
71 | if (httpEntity != null) {
72 | Bundle resultBundle = new Bundle();
73 | resultBundle.putString(BUNDLE_KEY_REQUEST_RESULT, EntityUtils.toString(httpEntity));
74 | receiver.send(statusCode, resultBundle);
75 | }
76 | else {
77 | receiver.send(statusCode, null);
78 | }
79 | }
80 | else {
81 | receiver.send(0, null);
82 |
83 | }
84 | }
85 | catch (IOException e) {
86 | receiver.send(0, null);
87 | } catch (URISyntaxException e) {
88 | e.printStackTrace();
89 | }
90 | }
91 |
92 | private HttpResponse doRequest(HttpRequestBase request) throws IOException {
93 | HttpClient client = new DefaultHttpClient();
94 |
95 | // HttpClient configuration omitted
96 |
97 | return client.execute(request);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter12/WebServiceActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter12;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 | import android.os.ResultReceiver;
9 | import android.view.View;
10 |
11 | import com.eat.R;
12 |
13 | public class WebServiceActivity extends Activity {
14 |
15 | private final static String TAG = WebServiceActivity.class.getSimpleName();
16 | private final static String getUrl = "http://dn.se"; // Dummy
17 | private final static String postUrl = "http://dn.se"; // Dummy
18 |
19 | private ResultReceiver mReceiver;
20 |
21 | public WebServiceActivity() {
22 | mReceiver = new ResultReceiver(new Handler()) {
23 | @Override
24 | protected void onReceiveResult(int resultCode, Bundle resultData) {
25 | int httpStatus = resultCode;
26 | String jsonResult = null;
27 | if (httpStatus == 200) { // OK
28 | if (resultData != null) {
29 | jsonResult= resultData.getString(WebService.BUNDLE_KEY_REQUEST_RESULT);
30 | // Omitted: Handle response
31 | }
32 | }
33 | else {
34 | // Handle error
35 | }
36 | }
37 |
38 | };
39 | }
40 |
41 | @Override
42 | public void onCreate(Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 | setContentView(R.layout.activity_web_service);
45 | }
46 |
47 | public void doPost(View v) {
48 | Intent intent = new Intent(this, WebService.class);
49 | intent.setData(Uri.parse(postUrl));
50 | intent.putExtra(WebService.INTENT_KEY_REQUEST_TYPE, WebService.POST);
51 | intent.putExtra(WebService.INTENT_KEY_JSON, "{\"foo\":\"bar\"}");
52 | intent.putExtra(WebService.INTENT_KEY_RECEIVER, mReceiver);
53 | startService(intent);
54 | }
55 |
56 | public void doGet(View v) {
57 | Intent intent = new Intent(this, WebService.class);
58 | intent.setData(Uri.parse(getUrl));
59 | intent.putExtra(WebService.INTENT_KEY_REQUEST_TYPE, WebService.GET);
60 | intent.putExtra(WebService.INTENT_KEY_RECEIVER, mReceiver);
61 | startService(intent);
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter13/Chapter13Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter13;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 | import com.eat.chapter12.WebServiceActivity;
10 |
11 | public class Chapter13Activity extends Activity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_chapter13);
17 | }
18 |
19 | public void onExpandableContactListActivity(View v) {
20 | startActivity(new Intent(this, ExpandableContactListActivity.class));
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter13/ExpandableContactListActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter13;
2 |
3 | import android.app.ExpandableListActivity;
4 | import android.content.AsyncQueryHandler;
5 | import android.content.ContentUris;
6 | import android.content.Context;
7 | import android.database.Cursor;
8 | import android.net.Uri;
9 | import android.os.Bundle;
10 | import android.provider.ContactsContract.CommonDataKinds.Phone;
11 | import android.provider.ContactsContract.Contacts;
12 | import android.widget.CursorTreeAdapter;
13 | import android.widget.SimpleCursorTreeAdapter;
14 |
15 |
16 | public class ExpandableContactListActivity extends ExpandableListActivity {
17 |
18 | private static final String[] CONTACTS_PROJECTION = new String[] {
19 | Contacts._ID,
20 | Contacts.DISPLAY_NAME
21 | };
22 | private static final int GROUP_ID_COLUMN_INDEX = 0;
23 |
24 | private static final String[] PHONE_NUMBER_PROJECTION = new String[] {
25 | Phone._ID,
26 | Phone.NUMBER
27 | };
28 |
29 | private static final int TOKEN_GROUP = 0;
30 | private static final int TOKEN_CHILD = 1;
31 |
32 | private QueryHandler mQueryHandler;
33 | private CursorTreeAdapter mAdapter;
34 |
35 | @Override
36 | public void onCreate(Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 |
39 | // Set up our adapter
40 | mAdapter = new MyExpandableListAdapter(
41 | this,
42 | android.R.layout.simple_expandable_list_item_1,
43 | android.R.layout.simple_expandable_list_item_1,
44 | new String[] { Contacts.DISPLAY_NAME }, // Name for group layouts
45 | new int[] { android.R.id.text1 },
46 | new String[] { Phone.NUMBER }, // Number for child layouts
47 | new int[] { android.R.id.text1 });
48 |
49 | setListAdapter(mAdapter);
50 |
51 | mQueryHandler = new QueryHandler(this, mAdapter);
52 |
53 | // Query for people
54 | mQueryHandler.startQuery(TOKEN_GROUP,
55 | null,
56 | Contacts.CONTENT_URI,
57 | CONTACTS_PROJECTION,
58 | Contacts.HAS_PHONE_NUMBER,
59 | null,
60 | Contacts.DISPLAY_NAME + " ASC");
61 | }
62 |
63 | @Override
64 | protected void onDestroy() {
65 | super.onDestroy();
66 | mQueryHandler.cancelOperation(TOKEN_GROUP);
67 | mQueryHandler.cancelOperation(TOKEN_CHILD);
68 | mAdapter.changeCursor(null);
69 | mAdapter = null;
70 | }
71 |
72 | private static final class QueryHandler extends AsyncQueryHandler {
73 | private CursorTreeAdapter mAdapter;
74 |
75 | public QueryHandler(Context context, CursorTreeAdapter adapter) {
76 | super(context.getContentResolver());
77 | this.mAdapter = adapter;
78 | }
79 |
80 | @Override
81 | protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
82 | switch (token) {
83 | case TOKEN_GROUP:
84 | mAdapter.setGroupCursor(cursor);
85 | break;
86 |
87 | case TOKEN_CHILD:
88 | int groupPosition = (Integer) cookie;
89 | mAdapter.setChildrenCursor(groupPosition, cursor);
90 | break;
91 | }
92 | }
93 | }
94 |
95 | public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
96 |
97 | // Note that the constructor does not take a Cursor. This is done to avoid querying the
98 | // database on the main thread.
99 | public MyExpandableListAdapter(Context context, int groupLayout,
100 | int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom,
101 | int[] childrenTo) {
102 |
103 | super(context, null, groupLayout, groupFrom, groupTo, childLayout, childrenFrom,
104 | childrenTo);
105 | }
106 |
107 | @Override
108 | protected Cursor getChildrenCursor(Cursor groupCursor) {
109 | // Given the group, we return a cursor for all the children within that group
110 |
111 | // Return a cursor that points to this contact's phone numbers
112 | Uri.Builder builder = Contacts.CONTENT_URI.buildUpon();
113 | ContentUris.appendId(builder, groupCursor.getLong(GROUP_ID_COLUMN_INDEX));
114 | builder.appendEncodedPath(Contacts.Data.CONTENT_DIRECTORY);
115 | Uri phoneNumbersUri = builder.build();
116 |
117 | mQueryHandler.startQuery(TOKEN_CHILD,
118 | groupCursor.getPosition(),
119 | phoneNumbersUri,
120 | PHONE_NUMBER_PROJECTION,
121 | Phone.MIMETYPE + "=?",
122 | new String[] { Phone.CONTENT_ITEM_TYPE },
123 | null);
124 |
125 | return null;
126 | }
127 | }
128 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter14/BasicActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter14;
2 |
3 | import android.app.Activity;
4 | import android.app.LoaderManager;
5 | import android.content.Loader;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.widget.TextView;
9 |
10 | import com.eat.R;
11 |
12 | public class BasicActivity extends Activity implements LoaderManager.LoaderCallbacks{
13 |
14 | private static final int BASIC_LOADER_ID = 0;
15 |
16 | TextView tvResult;
17 |
18 | public void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_basic);
21 | tvResult = (TextView) findViewById(R.id.text_result);
22 | getLoaderManager().initLoader(BASIC_LOADER_ID, null, this);
23 | }
24 |
25 | @Override
26 | public Loader onCreateLoader(int id, Bundle args) {
27 | return new BasicLoader(this);
28 | }
29 |
30 | @Override
31 | public void onLoadFinished(Loader loader, Integer data) {
32 | tvResult.setText(Integer.toString(data));
33 | }
34 |
35 | @Override
36 | public void onLoaderReset(Loader loader) {
37 | // Empty
38 | }
39 |
40 | public void onLoad(View v) {
41 | getLoaderManager().getLoader(BASIC_LOADER_ID).forceLoad();
42 | }
43 |
44 | public void onCancel(View v) {
45 | getLoaderManager().getLoader(BASIC_LOADER_ID).cancelLoad();
46 | }
47 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter14/BasicLoader.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter14;
2 |
3 | import android.content.AsyncTaskLoader;
4 | import android.content.Context;
5 | import android.os.SystemClock;
6 | import android.util.Log;
7 |
8 | import java.util.Random;
9 |
10 | public class BasicLoader extends AsyncTaskLoader{
11 |
12 | private static final String TAG = "BasicLoader";
13 |
14 | public BasicLoader(Context context) {
15 | super(context);
16 | }
17 |
18 | @Override
19 | protected boolean onCancelLoad() {
20 | Log.d(TAG, "onCancelLoad");
21 | return super.onCancelLoad();
22 | }
23 |
24 | @Override
25 | protected void onStartLoading() {
26 | super.onStartLoading();
27 | forceLoad();
28 | }
29 |
30 | @Override
31 | public Integer loadInBackground() {
32 | return loadData();
33 | }
34 |
35 | private int loadData() {
36 | SystemClock.sleep(3000);
37 | Random rand = new Random();
38 | int data = rand.nextInt(50);
39 | Log.d(TAG, "loadData - data = " + data);
40 | return data;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter14/Chapter14Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter14;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 | import com.eat.chapter13.ExpandableContactListActivity;
10 |
11 | public class Chapter14Activity extends Activity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.activity_chapter14);
17 | }
18 |
19 | public void onBasicActivity(View v) {
20 | startActivity(new Intent(this, BasicActivity.class));
21 | }
22 |
23 | public void onChromeBookmarkActivity(View v) {
24 | startActivity(new Intent(this, ChromeBookmarkActivity.class));
25 | }
26 |
27 | public void onContactActivity(View v) {
28 | startActivity(new Intent(this, ContactActivity.class));
29 | }
30 |
31 | public void onFileActivity(View v) {
32 | startActivity(new Intent(this, FileActivity.class));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter14/ChromeBookmarkActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter14;
2 |
3 | import android.app.*;
4 | import android.content.*;
5 | import android.database.Cursor;
6 | import android.net.Uri;
7 | import android.os.Bundle;
8 | import android.provider.Browser;
9 | import android.view.View;
10 | import android.widget.AdapterView;
11 | import android.widget.ListView;
12 | import android.widget.SimpleCursorAdapter;
13 |
14 | import com.eat.R;
15 |
16 | public class ChromeBookmarkActivity extends Activity implements LoaderManager.LoaderCallbacks {
17 |
18 | // Definition of bookmark access information.
19 | public interface ChromeBookmark {
20 | final static int ID = 1;
21 | final static Uri URI= Uri.parse("content://com.android.chrome.browser/bookmarks");
22 | final static String[] PROJECTION = {
23 | Browser.BookmarkColumns._ID,
24 | Browser.BookmarkColumns.TITLE,
25 | Browser.BookmarkColumns.URL
26 | };
27 | }
28 |
29 | // AsyncQueryHandler with convenience methods for insertion and deletion of bookmarks.
30 | public static class ChromeBookmarkAsyncHandler extends AsyncQueryHandler {
31 |
32 | public ChromeBookmarkAsyncHandler(ContentResolver cr) {
33 | super(cr);
34 | }
35 |
36 | public void insert(String name, String url) {
37 | ContentValues cv = new ContentValues();
38 | cv.put(Browser.BookmarkColumns.BOOKMARK, 1);
39 | cv.put(Browser.BookmarkColumns.TITLE, name);
40 | cv.put(Browser.BookmarkColumns.URL, url);
41 | startInsert(0, null, ChromeBookmark.URI, cv);
42 | }
43 |
44 | public void delete(String name) {
45 | String where = Browser.BookmarkColumns.TITLE + "=?";
46 | String[] args = new String[] { name };
47 | startDelete(0, null, ChromeBookmark.URI, where, args);
48 | }
49 | }
50 |
51 |
52 | ListView mListBookmarks;
53 | SimpleCursorAdapter mAdapter;
54 | ChromeBookmarkAsyncHandler mChromeBookmarkAsyncHandler;
55 |
56 | public void onCreate(Bundle savedInstanceState) {
57 | super.onCreate(savedInstanceState);
58 | setContentView(R.layout.activity_bookmarks);
59 | mListBookmarks = (ListView) findViewById(R.id.list_bookmarks);
60 |
61 | mChromeBookmarkAsyncHandler = new ChromeBookmarkAsyncHandler(getContentResolver());
62 |
63 | initAdapter();
64 |
65 | getLoaderManager().initLoader(ChromeBookmark.ID, null, this);
66 | }
67 |
68 | private void initAdapter() {
69 | mAdapter = new SimpleCursorAdapter(this,
70 | android.R.layout.simple_list_item_1, null,
71 | new String[] { Browser.BookmarkColumns.TITLE },
72 | new int[] { android.R.id.text1}, 0);
73 | mListBookmarks.setAdapter(mAdapter);
74 | mListBookmarks.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
75 | @Override
76 | public boolean onItemLongClick(AdapterView> adapterView, View view, int pos, long id) {
77 | Cursor c = ((SimpleCursorAdapter) adapterView.getAdapter()).getCursor();
78 | c.moveToPosition(pos);
79 | int i = c.getColumnIndex(Browser.BookmarkColumns.TITLE);
80 | mChromeBookmarkAsyncHandler.delete(c.getString(i));
81 | return true;
82 | }
83 | });
84 | }
85 |
86 | @Override
87 | public Loader onCreateLoader(int i, Bundle bundle) {
88 | return new CursorLoader(this, ChromeBookmark.URI,
89 | ChromeBookmark.PROJECTION, null, null,
90 | Browser.BookmarkColumns.TITLE + " ASC");
91 | }
92 |
93 | @Override
94 | public void onLoadFinished(Loader loader, Cursor newCursor) {
95 | mAdapter.swapCursor(newCursor);
96 | }
97 |
98 | @Override
99 | public void onLoaderReset(Loader loader) {
100 | mAdapter.swapCursor(null);
101 | }
102 |
103 |
104 | public void onAddBookmark(View v) {
105 | FragmentTransaction ft = getFragmentManager().beginTransaction();
106 | Fragment prev = getFragmentManager().findFragmentByTag("dialog");
107 | // Remove previous dialogs
108 | if (prev != null) {
109 | ft.remove(prev);
110 | }
111 | ft.addToBackStack(null);
112 | // Create and show the dialog.
113 | DialogFragment newFragment = EditBookmarkDialog.newInstance(mChromeBookmarkAsyncHandler);
114 | newFragment.show(ft, "dialog");
115 | }
116 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter14/ContactActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter14;
2 |
3 | import android.app.ListActivity;
4 | import android.app.LoaderManager;
5 | import android.content.CursorLoader;
6 | import android.content.Loader;
7 | import android.database.Cursor;
8 | import android.os.Bundle;
9 | import android.provider.ContactsContract;
10 | import android.widget.SimpleCursorAdapter;
11 |
12 | public class ContactActivity extends ListActivity implements LoaderManager.LoaderCallbacks{
13 |
14 | private static final int CONTACT_NAME_LOADER_ID = 0;
15 |
16 | // Projection that defines contact display name only
17 | static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
18 | ContactsContract.Contacts._ID,
19 | ContactsContract.Contacts.DISPLAY_NAME
20 | };
21 |
22 | SimpleCursorAdapter mAdapter;
23 |
24 | public void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | initAdapter();
27 | getLoaderManager().initLoader(CONTACT_NAME_LOADER_ID, null, this);
28 | }
29 |
30 | private void initAdapter() {
31 | mAdapter = new SimpleCursorAdapter(this,
32 | android.R.layout.simple_list_item_1, null,
33 | new String[] { ContactsContract.Contacts.DISPLAY_NAME },
34 | new int[] { android.R.id.text1}, 0);
35 | setListAdapter(mAdapter);
36 | }
37 |
38 | @Override
39 | public Loader onCreateLoader(int id, Bundle args) {
40 | return new CursorLoader(this, ContactsContract.Contacts.CONTENT_URI,
41 | CONTACTS_SUMMARY_PROJECTION, null, null,
42 | ContactsContract.Contacts.DISPLAY_NAME + " ASC");
43 | }
44 |
45 | @Override
46 | public void onLoadFinished(Loader loader, Cursor c) {
47 | mAdapter.swapCursor(c);
48 | }
49 |
50 | @Override
51 | public void onLoaderReset(Loader arg0) {
52 | mAdapter.swapCursor(null);
53 | }
54 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter14/EditBookmarkDialog.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter14;
2 |
3 | import android.app.DialogFragment;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.Button;
9 | import android.widget.EditText;
10 |
11 | import com.eat.R;
12 |
13 | public class EditBookmarkDialog extends DialogFragment {
14 |
15 | static EditBookmarkDialog newInstance(ChromeBookmarkActivity.ChromeBookmarkAsyncHandler asyncQueryHandler) {
16 | EditBookmarkDialog dialog = new EditBookmarkDialog(asyncQueryHandler);
17 | return dialog;
18 | }
19 |
20 | ChromeBookmarkActivity.ChromeBookmarkAsyncHandler mAsyncQueryHandler;
21 |
22 | public EditBookmarkDialog(ChromeBookmarkActivity.ChromeBookmarkAsyncHandler asyncQueryHandler) {
23 | mAsyncQueryHandler = asyncQueryHandler;
24 | }
25 |
26 | @Override
27 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
28 | Bundle savedInstanceState) {
29 | View v = inflater.inflate(R.layout.dialog_edit_bookmark, container, false);
30 | final EditText editName = (EditText) v.findViewById(R.id.edit_name);
31 | final EditText editUrl = (EditText) v.findViewById(R.id.edit_url);
32 | Button buttonSave = (Button) v.findViewById(R.id.button_save);
33 |
34 | buttonSave.setOnClickListener(new View.OnClickListener() {
35 | public void onClick(View v) {
36 | String name = editName.getText().toString();
37 | String url = editUrl.getText().toString();
38 | mAsyncQueryHandler.insert(name, url);
39 | dismiss();
40 | }
41 | });
42 |
43 | return v;
44 | }
45 |
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter14/FileActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter14;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.util.Log;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 |
10 | import java.io.BufferedOutputStream;
11 | import java.io.File;
12 | import java.io.FileOutputStream;
13 | import java.io.OutputStream;
14 |
15 | public class FileActivity extends Activity {
16 |
17 | private static final String TAG = "FileActivity";
18 |
19 | private static int mCount; // A count to append to file names
20 |
21 | public void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_file);
24 | }
25 |
26 | public void onAddFile(View v) {
27 | String filename = "testfile" + mCount++ + ".txt";
28 | File file = new File(this.getFilesDir(), filename);
29 | OutputStream out = null;
30 | try {
31 | out = new BufferedOutputStream(new FileOutputStream(file));
32 | out.write(new String("Test").getBytes("UTF-8"));
33 | out.close();
34 | } catch (Exception e){
35 |
36 | }
37 | Log.d(TAG, "onAddFile - path = " + file.getAbsolutePath());
38 |
39 | }
40 |
41 | public void onRemoveFiles(View v) {
42 | removeAllFiles();
43 | }
44 |
45 | private void removeAllFiles() {
46 | File dir = getFilesDir();
47 | File[] files = dir.listFiles();
48 | for (File file : files) {
49 | file.delete();
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter14/FileListFragment.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter14;
2 |
3 | import android.app.ListFragment;
4 | import android.app.LoaderManager;
5 | import android.content.Loader;
6 | import android.os.Bundle;
7 | import android.util.Log;
8 | import android.widget.ArrayAdapter;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 |
13 | public class FileListFragment extends ListFragment implements
14 | LoaderManager.LoaderCallbacks>{
15 |
16 | private static final int FILE_LOADER_ID = 1;
17 |
18 | private ArrayAdapter mFileAdapter;
19 | private List mFileNames = new ArrayList();
20 |
21 | @Override
22 | public void onActivityCreated(Bundle savedInstanceState) {
23 | super.onActivityCreated(savedInstanceState);
24 | getLoaderManager().initLoader(FILE_LOADER_ID, null, this);
25 | setEmptyText("No files in directory");
26 | setListShown(false);
27 |
28 | mFileAdapter = new ArrayAdapter(getActivity(),
29 | android.R.layout.simple_list_item_1, android.R.id.text1, mFileNames);
30 | mFileAdapter.setNotifyOnChange(true);
31 | setListAdapter(mFileAdapter);
32 | }
33 |
34 | @Override
35 | public Loader> onCreateLoader(int i, Bundle bundle) {
36 | return new FileLoader(getActivity());
37 | }
38 |
39 | @Override
40 | public void onLoadFinished(Loader> fileLoader,
41 | List fileNames) {
42 | mFileAdapter.clear();
43 | mFileAdapter.addAll(fileNames);
44 | setListShown(true);
45 | }
46 |
47 | @Override
48 | public void onLoaderReset(Loader> fileLoader) {
49 | mFileNames = null;
50 | mFileAdapter.clear();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter14/FileLoader.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter14;
2 |
3 | import android.content.AsyncTaskLoader;
4 | import android.content.Context;
5 | import android.os.FileObserver;
6 | import android.util.Log;
7 |
8 | import java.io.File;
9 | import java.util.Arrays;
10 | import java.util.List;
11 |
12 | /**
13 | * 1. Data observation
14 | * 2. Load data on background thread when the content has changed.
15 | * 3. Cache data
16 | * 4. Only deliver data when started.
17 | * 5. Release resources on reset.
18 | * 6. Cancel load.
19 | * 7. Handle deliverResult
20 | */
21 | public class FileLoader extends AsyncTaskLoader> {
22 | // Cache the list of file names.
23 | private List mFileNames;
24 |
25 |
26 | // 1. Data observation
27 | private class SdCardObserver extends FileObserver {
28 |
29 | public SdCardObserver(String path) {
30 | super(path, FileObserver.CREATE|FileObserver.DELETE);
31 | }
32 |
33 | @Override
34 | public void onEvent(int event, String path) {
35 | // Report that a content change has occurred.
36 | // This call will force a new asynchronous data load if the loader is started
37 | // otherwise it will keep a reference that the data has changed for future loads.
38 | onContentChanged();
39 | }
40 | }
41 |
42 | private SdCardObserver mSdCardObserver;
43 |
44 | public FileLoader(Context context) {
45 | super(context);
46 | String path = context.getFilesDir().getPath();
47 | mSdCardObserver = new SdCardObserver(path);
48 | }
49 |
50 |
51 |
52 | /**
53 | * Decide whether a load should be initiated or not.
54 | */
55 | @Override
56 | protected void onStartLoading() {
57 | super.onStartLoading();
58 | mSdCardObserver.startWatching();
59 |
60 | if (mFileNames != null) {
61 | // Return the cache
62 | deliverResult(mFileNames);
63 | }
64 |
65 | // Force a data load if there are no previous data
66 | // or if the content has been marked as changed earlier but not delivered.
67 | if (takeContentChanged() || mFileNames == null) {
68 | forceLoad();
69 | }
70 | }
71 |
72 | @Override
73 | public List loadInBackground() {
74 | File directory = getContext().getFilesDir();
75 | return Arrays.asList(directory.list());
76 | }
77 |
78 | @Override
79 | public void deliverResult(List data) {
80 | if (isReset()) {
81 | return;
82 | }
83 |
84 | // Cache the data
85 | mFileNames = data;
86 |
87 | // Only deliver result if the loader is started.
88 | if (isStarted()) {
89 | super.deliverResult(data);
90 | }
91 | }
92 |
93 | @Override
94 | protected void onStopLoading() {
95 | super.onStopLoading();
96 | cancelLoad();
97 | }
98 |
99 | @Override
100 | protected void onReset() {
101 | super.onReset();
102 | mSdCardObserver.stopWatching();
103 | clearResources();
104 | }
105 |
106 | private void clearResources() {
107 | mFileNames = null;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter2/Chapter2Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter2;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.eat.R;
7 |
8 | public class Chapter2Activity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_chapter2);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter3/Chapter3Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter3;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.eat.R;
7 |
8 | public class Chapter3Activity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_chapter3);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter4/Chapter4Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter4;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 |
10 | public class Chapter4Activity extends Activity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_chapter4);
16 | }
17 |
18 | public void onPipeActivity(View v) {
19 | startActivity(new Intent(this, PipeExampleActivity.class));
20 | }
21 |
22 | public void onLooperActivity(View v) {
23 | startActivity(new Intent(this, LooperActivity.class));
24 | }
25 |
26 | public void onConsumeAndQuitThreadActivity(View v) {
27 | startActivity(new Intent(this, ConsumeAndQuitThreadActivity.class));
28 | }
29 |
30 | public void onHandlerExampleActivity(View v) {
31 | startActivity(new Intent(this, HandlerExampleActivity.class));
32 | }
33 |
34 | public void onHandlerCallbackActivity(View v) {
35 | startActivity(new Intent(this, HandlerCallbackActivity.class));
36 | }
37 |
38 | public void onMQDebugActivity(View v) {
39 | startActivity(new Intent(this, MQDebugActivity.class));
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter4/ConsumeAndQuitThreadActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter4;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.os.Looper;
7 | import android.os.Message;
8 | import android.os.MessageQueue;
9 | import android.os.SystemClock;
10 |
11 | import java.util.Random;
12 |
13 |
14 | public class ConsumeAndQuitThreadActivity extends Activity {
15 |
16 |
17 | public void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 |
20 | final ConsumeAndQuitThread consumeAndQuitThread = new ConsumeAndQuitThread();
21 | consumeAndQuitThread.start();
22 | for (int i = 0; i < 10; i++) {
23 | new Thread(new Runnable() {
24 | @Override
25 | public void run() {
26 | for (int i = 0; i < 10; i++) {
27 | SystemClock.sleep(new Random().nextInt(10));
28 | consumeAndQuitThread.enqueueData(i);
29 | }
30 | }
31 | }).start();
32 | }
33 | }
34 |
35 | private static class ConsumeAndQuitThread extends Thread implements MessageQueue.IdleHandler {
36 |
37 | private static final String THREAD_NAME = "ConsumeAndQuitThread";
38 |
39 | public Handler mConsumerHandler;
40 | private boolean mIsFirstIdle = true;
41 |
42 | public ConsumeAndQuitThread() {
43 | super(THREAD_NAME);
44 | }
45 |
46 | @Override
47 | public void run() {
48 | Looper.prepare();
49 |
50 | mConsumerHandler = new Handler() {
51 | @Override
52 | public void handleMessage(Message msg) {
53 | // Consume data
54 | }
55 | };
56 | Looper.myQueue().addIdleHandler(this);
57 | Looper.loop();
58 | }
59 |
60 |
61 | @Override
62 | public boolean queueIdle() {
63 | if (mIsFirstIdle) {
64 | mIsFirstIdle = false;
65 | return true;
66 | }
67 | mConsumerHandler.getLooper().quit();
68 | return false;
69 | }
70 |
71 | public void enqueueData(int i) {
72 | mConsumerHandler.sendEmptyMessage(i);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter4/HandlerCallbackActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter4;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.os.Message;
7 | import android.view.View;
8 |
9 | import com.eat.R;
10 |
11 |
12 | public class HandlerCallbackActivity extends Activity implements Handler.Callback {
13 |
14 | @Override
15 | public void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.activity_handler_callback);
18 | }
19 |
20 | @Override
21 | public boolean handleMessage(Message msg) {
22 | switch (msg.what) {
23 | case 1:
24 | msg.what = 11;
25 | return true;
26 | default:
27 | msg.what = 22;
28 | return false;
29 | }
30 | }
31 |
32 | public void onHandlerCallback(View v) {
33 | Handler handler = new Handler(this) {
34 | @Override
35 | public void handleMessage(Message msg) {
36 | // Process message
37 | }
38 | };
39 | handler.sendEmptyMessage(1);
40 | handler.sendEmptyMessage(2);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter4/HandlerExampleActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter4;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.os.Looper;
7 | import android.os.Message;
8 | import android.os.SystemClock;
9 | import android.view.View;
10 | import android.widget.Button;
11 | import android.widget.ProgressBar;
12 | import android.widget.TextView;
13 |
14 | import com.eat.R;
15 |
16 | import java.util.Random;
17 |
18 |
19 | public class HandlerExampleActivity extends Activity {
20 |
21 | private final static int SHOW_PROGRESS_BAR = 1;
22 | private final static int HIDE_PROGRESS_BAR = 0;
23 | private BackgroundThread mBackgroundThread;
24 |
25 | private TextView mText;
26 | private Button mButton;
27 | private ProgressBar mProgressBar;
28 |
29 | @Override
30 | public void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 | setContentView(R.layout.activity_handler_example);
33 |
34 | mBackgroundThread = new BackgroundThread();
35 | mBackgroundThread.start();
36 |
37 | mText = (TextView) findViewById(R.id.text);
38 | mProgressBar = (ProgressBar) findViewById(R.id.progress);
39 | mButton = (Button) findViewById(R.id.button);
40 | mButton.setOnClickListener(new View.OnClickListener() {
41 | @Override
42 | public void onClick(View v) {
43 | mBackgroundThread.doWork();
44 | }
45 | });
46 | }
47 |
48 | @Override
49 | protected void onDestroy() {
50 | super.onDestroy();
51 | mBackgroundThread.exit();
52 | }
53 |
54 | private final Handler mUiHandler = new Handler() {
55 | public void handleMessage(Message msg) {
56 |
57 | switch(msg.what) {
58 | case SHOW_PROGRESS_BAR:
59 | mProgressBar.setVisibility(View.VISIBLE);
60 | break;
61 | case HIDE_PROGRESS_BAR:
62 | mText.setText(String.valueOf(msg.arg1));
63 | mProgressBar.setVisibility(View.INVISIBLE);
64 | break;
65 | }
66 | }
67 | };
68 |
69 | private class BackgroundThread extends Thread {
70 |
71 | private Handler mBackgroundHandler;
72 |
73 | public void run() {
74 | Looper.prepare();
75 | mBackgroundHandler = new Handler();
76 | Looper.loop();
77 | }
78 |
79 | public void doWork() {
80 | mBackgroundHandler.post(new Runnable() {
81 | @Override
82 | public void run() {
83 | Message uiMsg = mUiHandler.obtainMessage(SHOW_PROGRESS_BAR, 0,
84 | 0, null);
85 | mUiHandler.sendMessage(uiMsg);
86 |
87 | Random r = new Random();
88 | int randomInt = r.nextInt(5000);
89 | SystemClock.sleep(randomInt);
90 |
91 | uiMsg = mUiHandler.obtainMessage(HIDE_PROGRESS_BAR, randomInt,
92 | 0, null);
93 | mUiHandler.sendMessage(uiMsg);
94 | }
95 | });
96 | }
97 |
98 | public void exit() {
99 | mBackgroundHandler.getLooper().quit();
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter4/LooperActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter4;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.os.Looper;
7 | import android.os.Message;
8 | import android.view.View;
9 |
10 | import com.eat.R;
11 |
12 |
13 | public class LooperActivity extends Activity {
14 |
15 | LooperThread mLooperThread;
16 |
17 | private static class LooperThread extends Thread {
18 |
19 | public Handler mHandler;
20 |
21 | public void run() {
22 | Looper.prepare();
23 | mHandler = new Handler() {
24 | public void handleMessage(Message msg) {
25 | if(msg.what == 0) {
26 | doLongRunningOperation();
27 | }
28 | }
29 | };
30 | Looper.loop();
31 | }
32 |
33 | private void doLongRunningOperation() {
34 | // Add long running operation here.
35 | }
36 | }
37 |
38 | public void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 | setContentView(R.layout.activity_looper);
41 | mLooperThread = new LooperThread();
42 | mLooperThread.start();
43 | }
44 |
45 | public void onClick(View v) {
46 | if (mLooperThread.mHandler != null) {
47 | Message msg = mLooperThread.mHandler.obtainMessage(0);
48 | mLooperThread.mHandler.sendMessage(msg);
49 | }
50 | }
51 |
52 | protected void onDestroy() {
53 | super.onDestroy();
54 | mLooperThread.mHandler.getLooper().quit();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter4/MQDebugActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter4;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.os.Looper;
7 | import android.os.Message;
8 | import android.util.Log;
9 | import android.util.LogPrinter;
10 | import android.view.View;
11 |
12 | import com.eat.R;
13 |
14 |
15 | public class MQDebugActivity extends Activity {
16 |
17 | private static final String TAG = "EAT";
18 | Handler mWorkerHandler;
19 |
20 | public void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_mq_debug);
23 |
24 | Thread t = new Thread() {
25 | @Override
26 | public void run() {
27 | Looper.prepare();
28 | mWorkerHandler = new Handler() {
29 | @Override
30 | public void handleMessage(Message msg) {
31 | Log.d(TAG, "handleMessage - what = " + msg.what);
32 | }
33 | };
34 | Looper.loop();
35 | }
36 | };
37 | t.start();
38 | }
39 |
40 | // Called on button click, i.e. from the UI thread.
41 | public void onClick(View v) {
42 | mWorkerHandler.sendEmptyMessageDelayed(1, 2000);
43 | mWorkerHandler.sendEmptyMessage(2);
44 | mWorkerHandler.obtainMessage(3, 0, 0, new Object()).sendToTarget();
45 | mWorkerHandler.sendEmptyMessageDelayed(4, 300);
46 | mWorkerHandler.postDelayed(new Runnable() {
47 | @Override
48 | public void run() {
49 | Log.d(TAG, "Execute");
50 | }
51 | }, 400);
52 | mWorkerHandler.sendEmptyMessage(5);
53 |
54 | mWorkerHandler.dump(new LogPrinter(Log.DEBUG, TAG), "");
55 | }
56 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter4/PipeExampleActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter4;
2 |
3 | import android.text.Editable;
4 |
5 |
6 | import android.app.Activity;
7 | import android.os.Bundle;
8 | import android.text.TextWatcher;
9 | import android.util.Log;
10 | import android.widget.EditText;
11 | import com.eat.R;
12 |
13 | import java.io.IOException;
14 | import java.io.PipedReader;
15 | import java.io.PipedWriter;
16 |
17 |
18 | public class PipeExampleActivity extends Activity {
19 |
20 | private static final String TAG = "PipeExampleActivity";
21 | private EditText editText;
22 |
23 | PipedReader r;
24 | PipedWriter w;
25 |
26 | private Thread workerThread;
27 |
28 | public void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 |
31 | r = new PipedReader();
32 | w = new PipedWriter();
33 |
34 | try {
35 | w.connect(r);
36 | } catch (IOException e) {
37 | e.printStackTrace();
38 | }
39 |
40 | setContentView(R.layout.activity_pipe);
41 | editText = (EditText) findViewById(R.id.edit_text);
42 | editText.addTextChangedListener(new TextWatcher() {
43 | @Override
44 | public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
45 | }
46 |
47 | @Override
48 | public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
49 | try {
50 | // Only handle addition of characters
51 | if(count > before) {
52 | // Write the last entered character to the pipe
53 | w.write(charSequence.subSequence(before, count).toString());
54 | }
55 | } catch (IOException e) {
56 | e.printStackTrace();
57 | }
58 | }
59 |
60 | @Override
61 | public void afterTextChanged(Editable editable) {
62 | }
63 | });
64 |
65 | workerThread = new Thread(new TextHandlerTask(r));
66 | workerThread.start();
67 | }
68 |
69 | @Override
70 | protected void onDestroy() {
71 | super.onDestroy();
72 | workerThread.interrupt();
73 | try {
74 | r.close();
75 | w.close();
76 | } catch (IOException e) {
77 | }
78 | }
79 |
80 | private static class TextHandlerTask implements Runnable {
81 | private final PipedReader reader;
82 |
83 | public TextHandlerTask(PipedReader reader){
84 | this.reader = reader;
85 | }
86 | @Override
87 | public void run() {
88 | while(!Thread.currentThread().isInterrupted()){
89 | try {
90 | int i;
91 | while((i = reader.read()) != -1){
92 | char c = (char) i;
93 | //ADD TEXT PROCESSING LOGIC HERE
94 | Log.d(TAG, "char = " + c);
95 | }
96 |
97 | } catch (IOException e) {
98 | e.printStackTrace();
99 | }
100 | }
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter5/Chapter5Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter5;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 |
10 | public class Chapter5Activity extends Activity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_chapter5);
16 | }
17 |
18 | public void onMessengerOnewayActivity(View v) {
19 | startActivity(new Intent(this, MessengerOnewayActivity.class));
20 | }
21 |
22 | public void onMessengerTwowayActivity(View v) {
23 | startActivity(new Intent(this, MessengerTwowayActivity.class));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter5/MessengerOnewayActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter5;
2 |
3 | import android.app.Activity;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.ServiceConnection;
8 | import android.os.Bundle;
9 | import android.os.IBinder;
10 | import android.os.Message;
11 | import android.os.Messenger;
12 | import android.os.RemoteException;
13 | import android.view.View;
14 |
15 | import com.eat.R;
16 |
17 |
18 | /**
19 | * Activity passing messages to remote service via Messenger.
20 | */
21 | public class MessengerOnewayActivity extends Activity {
22 |
23 | private boolean mBound = false;
24 | private Messenger mRemoteService = null;
25 |
26 | private ServiceConnection mRemoteConnection = new ServiceConnection() {
27 |
28 | public void onServiceConnected(ComponentName className, IBinder service) {
29 | mRemoteService = new Messenger(service);
30 | mBound = true;
31 | }
32 |
33 | public void onServiceDisconnected(ComponentName className) {
34 | mRemoteService = null;
35 | mBound = false;
36 | }
37 | };
38 |
39 | public void onCreate(Bundle savedInstanceState) {
40 | super.onCreate(savedInstanceState);
41 | setContentView(R.layout.activity_messenger_client);
42 | }
43 |
44 | public void onBindClick(View v) {
45 | Intent intent = new Intent("com.eat.chapter5.ACTION_BIND");
46 | bindService(intent, mRemoteConnection, Context.BIND_AUTO_CREATE);
47 |
48 | }
49 |
50 | public void onUnbindClick(View v) {
51 | if (mBound) {
52 | unbindService(mRemoteConnection);
53 | mBound = false;
54 | }
55 |
56 | }
57 |
58 | public void onSendClick(View v) {
59 | if (mBound) {
60 | try {
61 | mRemoteService.send(Message.obtain(null, 2, 0, 0));
62 | } catch (RemoteException e) {
63 | // Empty
64 | }
65 | }
66 | }
67 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter5/MessengerTwowayActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter5;
2 |
3 | import android.app.Activity;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.ServiceConnection;
8 | import android.os.Bundle;
9 | import android.os.Handler;
10 | import android.os.IBinder;
11 | import android.os.Message;
12 | import android.os.Messenger;
13 | import android.os.RemoteException;
14 | import android.util.Log;
15 | import android.view.View;
16 |
17 | import com.eat.R;
18 |
19 |
20 | /**
21 | * Activity passing messages to remote service via Messenger.
22 | */
23 | public class MessengerTwowayActivity extends Activity {
24 | private static final String TAG = "MessengerTwowayActivity";
25 | private boolean mBound = false;
26 | private Messenger mRemoteService = null;
27 |
28 | private ServiceConnection mRemoteConnection = new ServiceConnection() {
29 |
30 | public void onServiceConnected(ComponentName className, IBinder service) {
31 | mRemoteService = new Messenger(service);
32 | mBound = true;
33 | }
34 |
35 | public void onServiceDisconnected(ComponentName className) {
36 | mRemoteService = null;
37 | mBound = false;
38 | }
39 | };
40 |
41 | public void onCreate(Bundle savedInstanceState) {
42 | super.onCreate(savedInstanceState);
43 | setContentView(R.layout.activity_messenger_client);
44 | }
45 |
46 | public void onBindClick(View v) {
47 | Intent intent = new Intent("com.eat.chapter5.ACTION_BIND");
48 | bindService(intent, mRemoteConnection, Context.BIND_AUTO_CREATE);
49 | }
50 |
51 | public void onUnbindClick(View v) {
52 | if (mBound) {
53 | unbindService(mRemoteConnection);
54 | mBound = false;
55 | }
56 |
57 | }
58 |
59 | public void onSendClick(View v) {
60 | if (mBound) {
61 | try {
62 | Message msg = Message.obtain(null, 1, 0, 0);
63 | msg.replyTo = new Messenger(new Handler() {
64 | @Override
65 | public void handleMessage(Message msg) {
66 | Log.d(TAG, "Message sent back - msg.what = " + msg.what);
67 | }
68 | });
69 | mRemoteService.send(msg);
70 | } catch (RemoteException e) {
71 | Log.e(TAG, e.getMessage());
72 | }
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter5/WorkerThreadService.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter5;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.os.Handler;
6 | import android.os.IBinder;
7 | import android.os.Looper;
8 | import android.os.Message;
9 | import android.os.Messenger;
10 | import android.os.RemoteException;
11 | import android.util.Log;
12 |
13 |
14 | public class WorkerThreadService extends Service {
15 |
16 | private static final String TAG = "WorkerThreadService";
17 | WorkerThread mWorkerThread;
18 | Messenger mWorkerMessenger;
19 |
20 | @Override
21 | public void onCreate() {
22 | super.onCreate();
23 | mWorkerThread = new WorkerThread();
24 | mWorkerThread.start();
25 | }
26 |
27 | // Worker thread has prepared a looper and handler.
28 | private void onWorkerPrepared() {
29 | Log.d(TAG, "onWorkerPrepared");
30 | mWorkerMessenger = new Messenger(mWorkerThread.mWorkerHandler);
31 | synchronized(this) {
32 | notifyAll();
33 | }
34 | }
35 |
36 | public IBinder onBind(Intent intent) {
37 | Log.d(TAG, "onBind");
38 | synchronized (this) {
39 | while (mWorkerMessenger == null) {
40 | try {
41 | wait();
42 | } catch (InterruptedException e) {
43 | // Empty
44 | }
45 | }
46 | }
47 | return mWorkerMessenger.getBinder();
48 | }
49 |
50 | @Override
51 | public void onDestroy() {
52 | super.onDestroy();
53 | mWorkerThread.quit();
54 | }
55 |
56 | private class WorkerThread extends Thread {
57 |
58 | Handler mWorkerHandler;
59 |
60 | @Override
61 | public void run() {
62 | Looper.prepare();
63 | mWorkerHandler = new Handler() {
64 | @Override
65 | public void handleMessage(Message msg) {
66 | switch (msg.what) {
67 | case 1:
68 | try {
69 | msg.replyTo.send(Message.obtain(null, msg.what, 0, 0));
70 | } catch (RemoteException e) {
71 | Log.e(TAG, e.getMessage());
72 | }
73 | break;
74 | case 2:
75 | Log.d(TAG, "Message received");
76 | break;
77 | }
78 |
79 | }
80 | };
81 | onWorkerPrepared();
82 | Looper.loop();
83 | }
84 |
85 | public void quit() {
86 | mWorkerHandler.getLooper().quit();
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter6/Chapter6Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter6;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | import com.eat.R;
7 |
8 | public class Chapter6Activity extends Activity {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_chapter6);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter7/Chapter7Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter7;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 | import com.eat.chapter5.MessengerOnewayActivity;
10 | import com.eat.chapter5.MessengerTwowayActivity;
11 |
12 | public class Chapter7Activity extends Activity {
13 |
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.activity_chapter7);
18 | }
19 |
20 | public void onThreadRetainActivity(View v) {
21 | startActivity(new Intent(this, ThreadRetainActivity.class));
22 | }
23 |
24 | public void onThreadRetainFragment(View v) {
25 | startActivity(new Intent(this, ThreadRetainWithFragmentActivity.class));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter7/ThreadFragment.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter7;
2 |
3 | import android.app.Activity;
4 | import android.app.Fragment;
5 | import android.os.Bundle;
6 | import android.os.SystemClock;
7 |
8 | public class ThreadFragment extends Fragment {
9 |
10 | private ThreadRetainWithFragmentActivity mActivity;
11 | private MyThread t;
12 |
13 | private class MyThread extends Thread {
14 |
15 | @Override
16 | public void run() {
17 | final String text = getTextFromNetwork();
18 | mActivity.setText(text);
19 | }
20 |
21 | // Long operation
22 | private String getTextFromNetwork() {
23 | // Simulate network operation
24 | SystemClock.sleep(5000);
25 | return "Text from network";
26 | }
27 | }
28 |
29 | @Override
30 | public void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 | setRetainInstance(true);
33 | }
34 |
35 | @Override
36 | public void onAttach(Activity activity) {
37 | super.onAttach(activity);
38 | mActivity = (ThreadRetainWithFragmentActivity) activity;
39 | }
40 |
41 | @Override
42 | public void onDetach() {
43 | super.onDetach();
44 | mActivity = null;
45 | }
46 |
47 | public void execute() {
48 | t = new MyThread();
49 | t.start();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter7/ThreadRetainActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter7;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.SystemClock;
6 | import android.view.View;
7 | import android.widget.TextView;
8 |
9 | import com.eat.R;
10 |
11 |
12 | public class ThreadRetainActivity extends Activity {
13 |
14 | private static class MyThread extends Thread {
15 | private ThreadRetainActivity mActivity;
16 |
17 | public MyThread(ThreadRetainActivity activity) {
18 | mActivity = activity;
19 | }
20 |
21 | private void attach(ThreadRetainActivity activity) {
22 | mActivity = activity;
23 | }
24 |
25 | @Override
26 | public void run() {
27 | final String text = getTextFromNetwork();
28 | mActivity.setText(text);
29 | }
30 |
31 | // Long operation
32 | private String getTextFromNetwork() {
33 | // Simulate network operation
34 | SystemClock.sleep(5000);
35 | return "Text from network";
36 | }
37 | }
38 |
39 | private static MyThread t;
40 | private TextView textView;
41 |
42 | @Override
43 | public void onCreate(Bundle savedInstanceState) {
44 | super.onCreate(savedInstanceState);
45 | setContentView(R.layout.activity_retain_thread);
46 | textView = (TextView) findViewById(R.id.text_retain);
47 | Object retainedObject = getLastNonConfigurationInstance();
48 | if (retainedObject != null) {
49 | t = (MyThread) retainedObject;
50 | t.attach(this);
51 | }
52 | }
53 |
54 | @Override
55 |
56 | public Object onRetainNonConfigurationInstance() {
57 | if (t != null && t.isAlive()) {
58 | return t;
59 | }
60 | return null;
61 | }
62 |
63 | public void onStartThread(View v) {
64 | t = new MyThread(this);
65 | t.start();
66 | }
67 |
68 | private void setText(final String text) {
69 | runOnUiThread(new Runnable() {
70 | @Override
71 | public void run() {
72 | textView.setText(text);
73 | }
74 | });
75 | }
76 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter7/ThreadRetainWithFragmentActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter7;
2 |
3 | import android.app.Activity;
4 | import android.app.FragmentManager;
5 | import android.app.FragmentTransaction;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.widget.TextView;
9 | import com.eat.R;
10 |
11 |
12 | public class ThreadRetainWithFragmentActivity extends Activity {
13 |
14 | private static final String TAG = "ThreadRetainActivity";
15 |
16 | private static final String KEY_TEXT = "key_text";
17 |
18 | private ThreadFragment mThreadFragment;
19 |
20 | private TextView mTextView;
21 |
22 |
23 | public void onCreate(Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | setContentView(R.layout.activity_retain_thread);
26 | mTextView = (TextView) findViewById(R.id.text_retain);
27 |
28 | FragmentManager manager = getFragmentManager();
29 | mThreadFragment = (ThreadFragment) manager.findFragmentByTag("threadfragment");
30 |
31 | if (mThreadFragment == null) {
32 | FragmentTransaction transaction = manager.beginTransaction();
33 | mThreadFragment = new ThreadFragment();
34 | transaction.add(mThreadFragment, "threadfragment");
35 | transaction.commit();
36 | }
37 | }
38 |
39 | @Override
40 | protected void onRestoreInstanceState(Bundle savedInstanceState) {
41 | super.onRestoreInstanceState(savedInstanceState);
42 | mTextView.setText(savedInstanceState.getString(KEY_TEXT));
43 | }
44 |
45 | @Override
46 | protected void onSaveInstanceState(Bundle outState) {
47 | super.onSaveInstanceState(outState);
48 | outState.putString(KEY_TEXT, (String)mTextView.getText());
49 | }
50 |
51 | // Method called to start a worker thread
52 | public void onStartThread(View v) {
53 | mThreadFragment.execute();
54 | }
55 |
56 | public void setText(final String text) {
57 | runOnUiThread(new Runnable() {
58 | @Override
59 | public void run() {
60 | mTextView.setText(text);
61 | }
62 | });
63 | }
64 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter8/ChainedNetworkActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter8;
2 |
3 | import android.app.Activity;
4 | import android.app.AlertDialog;
5 | import android.app.Dialog;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 | import android.os.HandlerThread;
9 | import android.os.Message;
10 | import android.os.Process;
11 | import android.os.SystemClock;
12 |
13 |
14 | public class ChainedNetworkActivity extends Activity {
15 |
16 | private static final int DIALOG_LOADING = 0;
17 |
18 | private static final int SHOW_LOADING = 1;
19 | private static final int DISMISS_LOADING = 2;
20 |
21 | Handler dialogHandler = new Handler() {
22 | @Override
23 | public void handleMessage(Message msg) {
24 | super.handleMessage(msg);
25 | switch (msg.what) {
26 | case SHOW_LOADING:
27 | showDialog(DIALOG_LOADING);
28 | break;
29 | case DISMISS_LOADING:
30 | dismissDialog(DIALOG_LOADING);
31 | }
32 | }
33 | };
34 |
35 | private class NetworkHandlerThread extends HandlerThread {
36 | private static final int STATE_A = 1;
37 | private static final int STATE_B = 2;
38 | private Handler mHandler;
39 |
40 | public NetworkHandlerThread() {
41 | super("NetworkHandlerThread", Process.THREAD_PRIORITY_BACKGROUND);
42 | }
43 |
44 | @Override
45 | protected void onLooperPrepared() {
46 | super.onLooperPrepared();
47 | mHandler = new Handler(getLooper()) {
48 | @Override
49 | public void handleMessage(Message msg) {
50 | super.handleMessage(msg);
51 | switch (msg.what) {
52 | case STATE_A:
53 | dialogHandler.sendEmptyMessage(SHOW_LOADING);
54 | String result = networkOperation1();
55 | if (result != null) {
56 | sendMessage(obtainMessage(STATE_B, result));
57 | } else {
58 | dialogHandler.sendEmptyMessage(DISMISS_LOADING);
59 | }
60 | break;
61 | case STATE_B:
62 | networkOperation2((String) msg.obj);
63 | dialogHandler.sendEmptyMessage(DISMISS_LOADING);
64 | break;
65 | }
66 | }
67 | };
68 | fetchDataFromNetwork();
69 | }
70 |
71 | private String networkOperation1() {
72 | SystemClock.sleep(2000); // Dummy
73 | return "A string";
74 | }
75 |
76 | private void networkOperation2(String data) {
77 | // Pass data to network, e.g. with HttpPost.
78 | SystemClock.sleep(2000); // Dummy
79 | }
80 |
81 | /**
82 | * Publicly exposed network operation
83 | */
84 | public void fetchDataFromNetwork() {
85 | mHandler.sendEmptyMessage(STATE_A);
86 | }
87 | }
88 |
89 | private NetworkHandlerThread mThread;
90 |
91 |
92 | public void onCreate(Bundle savedInstanceState) {
93 | super.onCreate(savedInstanceState);
94 | mThread = new NetworkHandlerThread();
95 | mThread.start();
96 | }
97 |
98 | @Override
99 | protected Dialog onCreateDialog(int id) {
100 | Dialog dialog = null;
101 | switch (id) {
102 | case DIALOG_LOADING:
103 | AlertDialog.Builder builder = new AlertDialog.Builder(this);
104 | builder.setMessage("Loading...");
105 | dialog = builder.create();
106 | break;
107 | }
108 | return dialog;
109 | }
110 |
111 | /**
112 | * Ensure that the background thread is terminated with the Activity.
113 | */
114 | @Override
115 | protected void onDestroy() {
116 | super.onDestroy();
117 | mThread.quit();
118 | }
119 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter8/Chapter8Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter8;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 |
10 | public class Chapter8Activity extends Activity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_chapter8);
16 | }
17 |
18 | public void onSharedPreferencesActivity(View v) {
19 | startActivity(new Intent(this, SharedPreferencesActivity.class));
20 | }
21 |
22 | public void onChainedNetworkActivity(View v) {
23 | startActivity(new Intent(this, ChainedNetworkActivity.class));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter8/MyHandlerThread.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter8;
2 |
3 | import android.os.*;
4 | import android.os.Process;
5 |
6 | public class MyHandlerThread extends HandlerThread {
7 |
8 | private Handler mHandler;
9 |
10 | public MyHandlerThread() {
11 | super("MyHandlerThread", Process.THREAD_PRIORITY_BACKGROUND);
12 | }
13 |
14 | @Override
15 | protected void onLooperPrepared() {
16 | super.onLooperPrepared();
17 | mHandler = new Handler(getLooper()) {
18 | @Override
19 | public void handleMessage(Message msg) {
20 | switch(msg.what) {
21 | case 1:
22 | // Handle message
23 | break;
24 | case 2:
25 | // Handle message
26 | break;
27 | }
28 | }
29 | };
30 | }
31 |
32 | public void publishedMethod1() {
33 | mHandler.sendEmptyMessage(1);
34 | }
35 | public void publishedMethod2() {
36 | mHandler.sendEmptyMessage(2);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter8/SharedPreferencesActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter8;
2 |
3 | import android.app.Activity;
4 | import android.content.SharedPreferences;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.os.HandlerThread;
8 | import android.os.Looper;
9 | import android.os.Message;
10 | import android.os.Process;
11 | import android.view.View;
12 | import android.widget.TextView;
13 |
14 | import com.eat.R;
15 |
16 |
17 | public class SharedPreferencesActivity extends Activity {
18 |
19 | TextView mTextValue;
20 |
21 | /**
22 | * Show read value in a TextView.
23 | */
24 | private Handler mUiHandler = new Handler() {
25 | @Override
26 | public void handleMessage(Message msg) {
27 | super.handleMessage(msg);
28 | if (msg.what == 0) {
29 | Integer i = (Integer)msg.obj;
30 | mTextValue.setText(Integer.toString(i));
31 | }
32 | }
33 | };
34 |
35 | private class SharedPreferenceThread extends HandlerThread {
36 |
37 | private static final String KEY = "key";
38 | private SharedPreferences mPrefs;
39 | private static final int READ = 1;
40 | private static final int WRITE = 2;
41 |
42 | private Handler mHandler;
43 |
44 | public SharedPreferenceThread() {
45 | super("SharedPreferenceThread", Process.THREAD_PRIORITY_BACKGROUND);
46 | mPrefs = getSharedPreferences("LocalPrefs", MODE_PRIVATE);
47 | }
48 |
49 | @Override
50 | protected void onLooperPrepared() {
51 | super.onLooperPrepared();
52 | mHandler = new Handler(getLooper()) {
53 | @Override
54 | public void handleMessage(Message msg) {
55 | switch(msg.what) {
56 | case READ:
57 | mUiHandler.sendMessage(mUiHandler.obtainMessage(0, mPrefs.getInt(KEY, 0)));
58 | break;
59 | case WRITE:
60 | SharedPreferences.Editor editor = mPrefs.edit();
61 | editor.putInt(KEY, (Integer)msg.obj);
62 | editor.commit();
63 | break;
64 | }
65 | }
66 | };
67 | }
68 |
69 | public void read() {
70 | mHandler.sendEmptyMessage(READ);
71 | }
72 | public void write(int i) {
73 | mHandler.sendMessage(Message.obtain(Message.obtain(mHandler, WRITE, i)));
74 | }
75 | }
76 |
77 | private int mCount;
78 | private SharedPreferenceThread mThread;
79 |
80 |
81 | @Override
82 | protected void onCreate(Bundle savedInstanceState) {
83 | super.onCreate(savedInstanceState);
84 | setContentView(R.layout.activity_shared_preferences);
85 | mTextValue = (TextView) findViewById(R.id.text_value);
86 | mThread = new SharedPreferenceThread();
87 | mThread.start();
88 | }
89 |
90 | /**
91 | * Write dummy value from the UI thread.
92 | */
93 | public void onButtonClickWrite(View v) {
94 | mThread.write(mCount++);
95 | }
96 |
97 | /**
98 | * Initiate a read from the UI thread.
99 | */
100 | public void onButtonClickRead(View v) {
101 | mThread.read();
102 | }
103 |
104 | /**
105 | * Ensure that the background thread is terminated with the Activity.
106 | */
107 | @Override
108 | protected void onDestroy() {
109 | super.onDestroy();
110 | mThread.quit();
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter9/Chapter9Activity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter9;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.eat.R;
9 |
10 | public class Chapter9Activity extends Activity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_chapter9);
16 | }
17 |
18 | public void onInvokeActivity(View v) {
19 | startActivity(new Intent(this, InvokeActivity.class));
20 | }
21 |
22 | public void onECSImageDownloaderActivity(View v) {
23 | startActivity(new Intent(this, ECSImageDownloaderActivity.class));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter9/ECSImageDownloaderActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter9;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.os.Bundle;
7 | import android.os.SystemClock;
8 | import android.widget.ImageView;
9 | import android.widget.LinearLayout;
10 |
11 | import com.eat.R;
12 |
13 | import java.util.Random;
14 | import java.util.concurrent.Callable;
15 | import java.util.concurrent.ExecutionException;
16 | import java.util.concurrent.ExecutorCompletionService;
17 | import java.util.concurrent.ExecutorService;
18 | import java.util.concurrent.Executors;
19 | import java.util.concurrent.Future;
20 | import java.util.concurrent.TimeUnit;
21 |
22 |
23 | public class ECSImageDownloaderActivity extends Activity {
24 |
25 | private static final String TAG = "ECSImageDownloaderActivity";
26 |
27 | private LinearLayout layoutImages;
28 |
29 |
30 | private class ImageDownloadTask implements Callable {
31 |
32 | @Override
33 | public Bitmap call() throws Exception {
34 | return downloadRemoteImage();
35 | }
36 |
37 | private Bitmap downloadRemoteImage() {
38 | SystemClock.sleep((int) (5000f - new Random().nextFloat() * 5000f));
39 | return BitmapFactory.decodeResource(ECSImageDownloaderActivity.this.getResources(), R.drawable.ic_launcher);
40 | }
41 | }
42 |
43 | private class DownloadCompletionService extends ExecutorCompletionService {
44 |
45 | private ExecutorService mExecutor;
46 |
47 | public DownloadCompletionService(ExecutorService executor) {
48 | super(executor);
49 | mExecutor = executor;
50 | }
51 |
52 | public void shutdown() {
53 | mExecutor.shutdown();
54 | }
55 |
56 | public boolean isTerminated() {
57 | return mExecutor.isTerminated();
58 | }
59 | }
60 |
61 | private class ConsumerThread extends Thread {
62 |
63 | private DownloadCompletionService mEcs;
64 |
65 | private ConsumerThread(DownloadCompletionService ecs) {
66 | this.mEcs = ecs;
67 | }
68 |
69 | @Override
70 | public void run() {
71 | super.run();
72 | try {
73 | while(!mEcs.isTerminated()) {
74 | Future future = mEcs.poll(1, TimeUnit.SECONDS);
75 | if (future != null) {
76 | addImage(future.get());
77 | }
78 | }
79 | } catch (InterruptedException e) {
80 | e.printStackTrace();
81 | } catch (ExecutionException e) {
82 | e.printStackTrace();
83 | }
84 | }
85 | }
86 |
87 | public void onCreate(Bundle savedInstanceState) {
88 | super.onCreate(savedInstanceState);
89 | setContentView(R.layout.activity_ecs_image_downloader);
90 | layoutImages = (LinearLayout) findViewById(R.id.layout_images);
91 |
92 | DownloadCompletionService ecs = new DownloadCompletionService(Executors.newCachedThreadPool());
93 | new ConsumerThread(ecs).start();
94 |
95 | for (int i = 0; i < 5; i++) {
96 | ecs.submit(new ImageDownloadTask());
97 | }
98 |
99 | ecs.shutdown();
100 | }
101 |
102 |
103 | private void addImage(final Bitmap image) {
104 | runOnUiThread(new Runnable() {
105 | @Override
106 | public void run() {
107 | ImageView iv = new ImageView(ECSImageDownloaderActivity.this);
108 | iv.setImageBitmap(image);
109 | layoutImages.addView(iv);
110 | }
111 | });
112 | }
113 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter9/InvokeActivity.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter9;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.SystemClock;
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.widget.TextView;
9 |
10 | import com.eat.R;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 | import java.util.concurrent.Callable;
15 | import java.util.concurrent.ExecutionException;
16 | import java.util.concurrent.Executors;
17 | import java.util.concurrent.Future;
18 | import java.util.concurrent.ThreadPoolExecutor;
19 |
20 |
21 | public class InvokeActivity extends Activity {
22 |
23 |
24 | private static final String TAG = "InvokeActivity";
25 |
26 | private TextView textStatus;
27 |
28 | public void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_invoke);
31 | textStatus = (TextView) findViewById(R.id.text_status);
32 | }
33 |
34 |
35 | public void onButtonClick(View v) {
36 |
37 | SimpleExecutor simpleExecutor = new SimpleExecutor();
38 | simpleExecutor.execute(new Runnable() {
39 | @Override
40 | public void run() {
41 | List> tasks = new ArrayList>();
42 | tasks.add(new Callable() {
43 | @Override
44 | public String call() throws Exception {
45 | return getFirstPartialDataFromNetwork();
46 | }
47 | });
48 | tasks.add(new Callable() {
49 | @Override
50 | public String call() throws Exception {
51 | return getSecondPartialDataFromNetwork();
52 | }
53 | });
54 |
55 | ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(2);
56 | try {
57 | Log.d(TAG, "invokeAll");
58 | List> futures = executor.invokeAll(tasks);
59 | Log.d(TAG, "invokeAll after");
60 |
61 | final String mashedData = mashupResult(futures);
62 |
63 | textStatus.post(new Runnable() {
64 | @Override
65 | public void run() {
66 | textStatus.setText(mashedData);
67 | }
68 | });
69 | Log.d(TAG, "mashedData = " + mashedData);
70 |
71 | } catch (InterruptedException e) {
72 | e.printStackTrace();
73 | } catch (ExecutionException e) {
74 | e.printStackTrace();
75 | }
76 |
77 | executor.shutdown();
78 | }
79 | });
80 | }
81 |
82 | private String getFirstPartialDataFromNetwork() {
83 | Log.d(TAG, "ProgressReportingTask 1 started");
84 | SystemClock.sleep(10000);
85 | Log.d(TAG, "ProgressReportingTask 1 done");
86 | return "MockA";
87 | }
88 |
89 | private String getSecondPartialDataFromNetwork() {
90 | Log.d(TAG, "ProgressReportingTask 2 started");
91 | SystemClock.sleep(2000);
92 | Log.d(TAG, "ProgressReportingTask 2 done");
93 | return "MockB";
94 | }
95 |
96 | private String mashupResult(List> futures) throws ExecutionException, InterruptedException {
97 | StringBuilder builder = new StringBuilder();
98 | for (Future future : futures) {
99 | builder.append(future.get());
100 | }
101 | return builder.toString();
102 | }
103 | }
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter9/LowPriorityThreadFactory.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter9;
2 |
3 | import android.util.Log;
4 |
5 | import java.util.concurrent.ThreadFactory;
6 |
7 | class LowPriorityThreadFactory implements ThreadFactory {
8 |
9 | private static final String TAG = "LowPriorityThreadFactory";
10 | private static int count = 1;
11 |
12 | public Thread newThread(Runnable r) {
13 | Thread t = new Thread(r);
14 | t.setName("LowPrio " + count++);
15 | t.setPriority(4);
16 | t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
17 | {
18 | @Override
19 | public void uncaughtException(Thread t, Throwable e)
20 | {
21 | Log.d(TAG, "Thread = " + t.getName() + ", error = " + e.getMessage());
22 | }
23 | });
24 | return t;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter9/PrestartedCores.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter9;
2 |
3 | import android.util.Log;
4 |
5 | import java.util.concurrent.BlockingQueue;
6 | import java.util.concurrent.LinkedBlockingQueue;
7 | import java.util.concurrent.ThreadPoolExecutor;
8 | import java.util.concurrent.TimeUnit;
9 |
10 | public class PrestartedCores {
11 |
12 |
13 | private static final String TAG = "PrestartedCores";
14 |
15 | public void preloadedQueue() {
16 |
17 | BlockingQueue preloadedQueue = new LinkedBlockingQueue();
18 | final String[] alphabet = {"Alpha","Beta", "Gamma","Delta","Epsilon","Zeta"};
19 | for(int i = 0; i < alphabet.length; i++){
20 | final int j = i;
21 | preloadedQueue.add(new Runnable() {
22 | @Override
23 | public void run() {
24 | Log.d(TAG, alphabet[j]);
25 |
26 | }
27 | });
28 | }
29 | ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 1, TimeUnit.SECONDS, preloadedQueue);
30 | executor.prestartAllCoreThreads();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter9/SimpleExecutor.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter9;
2 |
3 | import java.util.concurrent.Executor;
4 |
5 | public class SimpleExecutor implements Executor {
6 | @Override
7 | public void execute(Runnable runnable) {
8 | new Thread(runnable).start();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/java/com/eat/chapter9/TaskTrackingThreadPool.java:
--------------------------------------------------------------------------------
1 | package com.eat.chapter9;
2 |
3 |
4 | import android.util.Log;
5 |
6 | import java.util.concurrent.LinkedBlockingQueue;
7 | import java.util.concurrent.ThreadPoolExecutor;
8 | import java.util.concurrent.TimeUnit;
9 | import java.util.concurrent.atomic.AtomicInteger;
10 |
11 | public class TaskTrackingThreadPool extends ThreadPoolExecutor{
12 |
13 | private static final String TAG = "CustomThreadPool";
14 |
15 | private AtomicInteger mTaskCount = new AtomicInteger(0);
16 |
17 | public TaskTrackingThreadPool() {
18 | super(3, 3, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue());
19 | }
20 |
21 | @Override
22 | protected void beforeExecute(Thread t, Runnable r) {
23 | super.beforeExecute(t, r);
24 | Log.d(TAG, "beforeExecute - thread = " + t.getName());
25 | mTaskCount.getAndIncrement();
26 | }
27 |
28 | @Override
29 | protected void afterExecute(Runnable r, Throwable t) {
30 | super.afterExecute(r, t);
31 | Log.d(TAG, "afterExecute - thread = " + Thread.currentThread().getName() + "t = " + t);
32 | mTaskCount.getAndDecrement();
33 | }
34 |
35 | @Override
36 | protected void terminated() {
37 | super.terminated();
38 | Log.d(TAG, "terminated - thread = " + Thread.currentThread().getName());
39 | }
40 |
41 | public int getNbrOfTasks() {
42 | return mTaskCount.get();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andersgoransson/eatbookexamples/b6476cba9d931982b2f8c07a5fb7c529b3ba73d4/EatApplication/Eat/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andersgoransson/eatbookexamples/b6476cba9d931982b2f8c07a5fb7c529b3ba73d4/EatApplication/Eat/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andersgoransson/eatbookexamples/b6476cba9d931982b2f8c07a5fb7c529b3ba73d4/EatApplication/Eat/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andersgoransson/eatbookexamples/b6476cba9d931982b2f8c07a5fb7c529b3ba73d4/EatApplication/Eat/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_alarm_broadcast.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
13 |
14 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_basic.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
11 |
12 |
18 |
24 |
25 |
26 |
31 |
32 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_bluetooth.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
13 |
14 |
20 |
21 |
28 |
29 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_bookmarks.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_bound_local_service_async_client.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
13 |
14 |
20 |
21 |
29 |
30 |
31 |
34 |
35 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_bound_local_service_sync_client.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
20 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
17 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter11.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
21 |
26 |
31 |
32 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter12.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter13.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
17 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter14.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
21 |
26 |
31 |
32 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
21 |
26 |
31 |
36 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter6.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter7.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_chapter9.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
16 |
21 |
22 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_download_service.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
13 |
14 |
20 |
21 |
29 |
30 |
31 |
34 |
35 |
42 |
43 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_ecs_image_downloader.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_file.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
11 |
12 |
18 |
19 |
25 |
26 |
27 |
31 |
32 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_file_download.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
14 |
15 |
20 |
21 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_futuretask_preload.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
12 |
16 |
22 |
23 |
24 |
28 |
29 |
35 |
36 |
42 |
43 |
44 |
48 |
52 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_handler_callback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
12 |
13 |
19 |
20 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_handler_example.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
19 |
20 |
28 |
29 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_invoke.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
19 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_looper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_messenger_client.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
12 |
18 |
25 |
26 |
27 |
28 |
32 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_mq_debug.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_pipe.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_retain_thread.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
15 |
16 |
23 |
24 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_shared_preferences.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
11 |
15 |
21 |
27 |
28 |
33 |
34 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_start.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
17 |
24 |
31 |
32 |
33 |
36 |
43 |
49 |
50 |
51 |
54 |
60 |
67 |
68 |
69 |
72 |
78 |
84 |
85 |
86 |
89 |
95 |
101 |
102 |
103 |
106 |
112 |
118 |
119 |
120 |
123 |
129 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/activity_web_service.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
13 |
14 |
20 |
21 |
28 |
29 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/layout/dialog_edit_bookmark.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
13 |
19 |
24 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/menu/start.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
7 |
--------------------------------------------------------------------------------
/EatApplication/Eat/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | EAT examples
5 | Hello world!
6 | Settings
7 | PipeActivity
8 | Send message
9 | Send messages
10 |
11 |
12 |
--------------------------------------------------------------------------------
/EatApplication/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | mavenCentral()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:0.12.2'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | mavenCentral()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/EatApplication/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Settings specified in this file will override any Gradle settings
5 | # configured through the IDE.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/EatApplication/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/andersgoransson/eatbookexamples/b6476cba9d931982b2f8c07a5fb7c529b3ba73d4/EatApplication/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/EatApplication/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Aug 14 22:22:34 CEST 2014
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
7 |
--------------------------------------------------------------------------------
/EatApplication/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/EatApplication/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/EatApplication/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':Eat'
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | eatbookexamples
2 | ===============
3 |
4 | Example code from the Efficient Android Threading book.
5 |
6 | #### Acknowledgements
7 | Rick Isaacs - For working through all code samples in the book and providing me with feedback.
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------