@mSolo
2015-04-23T16:42:57.000000Z
字数 8713
阅读 2083
Android
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidbook.library.testlibraryapp"
sharedUserId="com.androidbook.mysharedusrid"
...
//Identify package you want to use
String targetPackageName="com.androidbook.samplepackage1";
//Decide on an appropriate context flag
int flag=Context.CONTEXT_RESTRICTED;
//Get the target context through one of your activities
Activity myContext = ……;
Context targetContext = myContext.createPackageContext(targetPackageName, flag);
//Use context to resolve file paths
Resources res = targetContext.getResources();
File path = targetContext.getFilesDir();
r = new PipedReader();
w = new PipedWriter();
try {
w.connect(r);
} catch (IOException e) {
e.printStackTrace();
}
A
handler
is a mechanism to drop a message on the main queue(Looper
) so that the message can be processed at a later point in time by the main thread.
a). More precisely, the queue attached to the thread on which the handler is instantiated
b). The message that is dropped has an internal reference pointing to the handler that dropped it.
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable(){
public void run() {
// do some work on the main thread.
}
});
handler.postAtFrontOfQueue(new Runnable(){
public void run() {
// do some work on the main thread.
}
});
handler.postDelayed(new Runnable(){
public void run() {
// do some work on the main thread in 10 seconds time
}
}, TimeUnit.SECONDS.toMillis(10));
final Runnable runnable = new Runnable(){
public void run() {
// … do some work
}
};
handler.postDelayed(runnable, TimeUnit.SECONDS.toMillis(10));
Button cancel = (Button) findViewById(R.id.cancel);
cancel.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
handler.removeCallbacks(runnable);
}
});
interface IdleHandler { boolean queueIdle(); }
Queue.removeIdleHandler()
// Get the message queue of the current thread.
MessageQueue mq = Looper.myQueue();
// Create and register an idle listener.
MessageQueue.IdleHandler idleHandler = new MessageQueue.IdleHandler();
mq.addIdleHandler(idleHandler)
// Unregister an idle listener.
mq.removeIdleHandler(idleHandler)
boolean post(Runnable r)
boolean postAtFrontOfQueue(Runnable r)
boolean postAtTime(Runnable r, Object token, long uptimeMillis)
boolean postAtTime(Runnable r, long uptimeMillis)
boolean postDelayed(Runnable r, long delayMillis)
boolean sendMessage(Message msg)
boolean sendMessageAtFrontOfQueue(Message msg)
boolean sendMessageAtTime(Message msg, long uptimeMillis)
boolean sendMessageDelayed(Message msg, long delayMillis)
boolean sendEmptyMessage(int what)
boolean sendEmptyMessageAtTime(int what, long uptimeMillis)
boolean sendEmptyMessageDelayed(int what, long delayMillis)
removeCallbacks(Runnable r)
removeCallbacks(Runnable r, Object token)
removeMessages(int what)
removeMessages(int what, Object object)
removeCallbacksAndMessages(Object token)
private void postFromUiThreadToUiThread() {
new Handler().post(new Runnable() { ... });
// The code at this point is part of a message being processed
// and is executed before the posted message.
}
private void postFromUiThreadToUiThread() {
runOnUiThread(new Runnable() { ... });
// The code at this point is executed after the message.
}
A
Looper
is a mechanism that quite literally loops forever, waiting for Messages to be added to its queue and dispatching them to targetHandlers
.
class SimpleLooper extends Thread {
public Handler handler;
public void run() {
Looper.prepare();
handler = new Handler();
Looper.loop();
}
}
Looper.getMainLooper()
quitSafely()
was added in API level 18 (Jelly Bean 4.3)Message m = new Message();
Message m = Message.obtain();
Message m = Message.obtain(Handler h);
Message m = Message.obtain(Handler h, int what);
Message m = Message.obtain(Handler h, int what, Object o);
Message m = Message.obtain(Handler h, int what, int arg1, int arg2);
Message m = Message.obtain(Handler h, int what, int arg1, int arg2, Object o);
Message m = Message.obtain(Handler h, Runnable task);
Message m = Message.obtain(Message originalMsg);
Sending Messages versus posting Runnables
The runtime difference mostly comes down to efficiency. Creating new instances of Runnable each time we want our Handler to do something adds garbage collection overhead, while sending messages re-uses Message instances, which are sourced from an application-wide pool.
Thread t = Thread.currentThread();
t.getId();
t.getName();
t.getPriority();
t.getThreadGroup().getName();
public static void logThreadSignature(){
Log.d("ThreadUtils", getThreadSignature());
}
public class WorkerThreadRunnable implements Runnable
{
//the handler to communicate with the main thread Set this in the constructor
Handler statusBackMainThreadHandler = null;
public WorkerThreadRunnable(Handler h) {
statusBackMainThreadHandler = h;
}
public void run() {
informStart();
for(int i=1;i <= 5;i++) {
//In the real world instead of sleeping work will be done here.
Utils.sleepForInSecs(1);
//Report back the work is progressing
informMiddle(i);
}
informFinish();
}
public void informStart() {
Message m = this.statusBackMainThreadHandler.obtainMessage();
m.setData(Utils.getStringAsABundle("starting run"));
this.statusBackmainThreadHandler.sendMessage(m);
}
// ...
}
protected Result doInBackground(Params… params)
protected void onPreExecute() // Main Thread
protected void onProgressUpdate(Progress… values) // Main Thread
protected void onPostExecute(Result result) // Main Thread
protected void onCancelled(Result result)
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params… params)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, params);
private static final Queue<Runnable> QUEUE = new LinkedBlockingQueue<Runnable>();
public static final Executor MY_EXECUTOR =
new ThreadPoolExecutor(4, 8, 1, TimeUnit.MINUTES, QUEUE);
task.executeOnExecutor(MY_EXECUTOR, params);
A common usage of AsyncTask is to declare it as an anonymous inner class of the host Activity, which creates an implicit reference to the Activity and an even bigger memory leak.
setRetainInstance(true)
on our Fragment(onCreate()
) so that it survives across Activity restarts.<your-package-name>.intent.action.YOUR_ACTION_NAME
public static void invokeMyApplication(Activity parentActivity) {
String actionName= "com.androidbook.intent.action.ShowBasicView";
Intent intent = new Intent(actionName);
parentActivity.startActivity(intent);
}
android.intent.action.DIAL
<activity......>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http"/>
<data android:scheme="https"/>
</intent-filter>
</activity>
setComponent(ComponentName name);
setClassName(String packageName, String classNameInThatPackage);
setClassName(Context context, String classNameInThatContext);
setClass(Context context, Class classObjectInThatContext);
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.android.contacts",
"com.android.contacts.DialContactsEntryActivity");
startActivity(intent);
//Go to home screen
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_HOME);
startActivity(mainIntent);
Action | Description |
---|---|
ACTION_BATTERY_CHANGED | Sent when the battery charge level or charging state changes |
ACTION_BOOT_COMPLETED | Sent when the platform completes booting |
ACTION_PACKAGE_ADDED | Sent when a package is added to the platform |
ACTION_PACKAGE_REMOVED | Sent when a package is removed from the platform |
ACTION_TIME_CHANGED | Sent when the user changes the time on the device |
ACTION_TIME_TICK | Sent every minute to indicate that time is ticking |
ACTION_TIMEZONE_CHANGED | Sent when the user changes the time |