編輯:關於Android編程
@Override public void startActivity(Intent intent, Bundle options) { warnIfCallingFromSystemProcess(); if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { throw new AndroidRuntimeException( "Calling startActivity() from outside of an Activity " + " context requires the FLAG_ACTIVITY_NEW_TASK flag." + " Is this really what you want?"); } mMainThread.getInstrumentation().execStartActivity( getOuterContext(), mMainThread.getApplicationThread(), null, (Activity)null, intent, -1, options); }
// 先獲取到當前的ActivityThread對象 Class activityThreadClass = Class.forName("android.app.ActivityThread"); Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread"); currentActivityThreadMethod.setAccessible(true); Object currentActivityThread = currentActivityThreadMethod.invoke(null);
package com.example.hookstartactivity; import java.lang.reflect.Method; import android.app.Activity; import android.app.Instrumentation; import android.app.Instrumentation.ActivityResult; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.IBinder; import android.util.Log; public class InstrumentationProxy extends Instrumentation { public static final String TAG = "InstrumentationProxy"; public static final String EXEC_START_ACTIVITY = "execStartActivity"; // ActivityThread裡面原始的Instrumentation對象,這裡千萬不能寫成mInstrumentation,這樣寫 //拋出異常,已親測試,所以這個地方就要注意了 public Instrumentation oldInstrumentation; //通過構造函數來傳遞對象 public InstrumentationProxy(Instrumentation mInstrumentation) { oldInstrumentation = mInstrumentation; } //這個方法是由於原始方法裡面的Instrumentation有execStartActivity方法來定的 public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { Log.d(TAG, "\n打印調用startActivity相關參數: \n" + "who = [" + who + "], " + "\ncontextThread = [" + contextThread + "], \ntoken = [" + token + "], " + "\ntarget = [" + target + "], \nintent = [" + intent + "], \nrequestCode = [" + requestCode + "], \noptions = [" + options + "]"); Log.i(TAG, "------------hook success------------->"); Log.i(TAG, "這裡可以做你在打開StartActivity方法之前的事情"); Log.i(TAG, "------------hook success------------->"); Log.i(TAG, ""); //由於這個方法是隱藏的,所以需要反射來調用,先找到這方法 try { Method execStartActivity = Instrumentation.class.getDeclaredMethod( EXEC_START_ACTIVITY, Context.class, IBinder.class, IBinder.class, Activity.class, Intent.class, int.class, Bundle.class); execStartActivity.setAccessible(true); return (ActivityResult) execStartActivity.invoke(oldInstrumentation, who, contextThread, token, target, intent, requestCode, options); } catch (Exception e) { //如果你在這個類的成員變量Instrumentation的實例寫錯mInstrument,代碼講會執行到這裡來 throw new RuntimeException("if Instrumentation paramerter is mInstrumentation, hook will fail"); } } }
package com.example.hookstartactivity; import java.lang.reflect.Field; import java.lang.reflect.Method; import android.app.Application; import android.app.Instrumentation; import android.util.Log; public class MyApplication extends Application { public static final String TAG = "MyApplication"; public static final String ACTIVIT_THREAD = "android.app.ActivityThread"; public static final String CURRENT_ACTIVITY_THREAD = "currentActivityThread"; public static final String INSTRUMENTATION = "mInstrumentation"; @Override public void onCreate() { try { //這個方法一般是寫在Application的oncreate函數裡面,如果你寫在activity裡面的oncrate函數裡面就已經晚了 attachContext(); } catch (Exception e) { e.printStackTrace(); } } public static void attachContext() throws Exception{ //獲取當前的ActivityThread對象 Class activityThreadClass = Class.forName(ACTIVIT_THREAD); Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod(CURRENT_ACTIVITY_THREAD); currentActivityThreadMethod.setAccessible(true); Object currentActivityThread = currentActivityThreadMethod.invoke(null); //拿到在ActivityThread類裡面的原始mInstrumentation對象 Field mInstrumentationField = activityThreadClass.getDeclaredField(INSTRUMENTATION); mInstrumentationField.setAccessible(true); Instrumentation mInstrumentation = (Instrumentation) mInstrumentationField.get(currentActivityThread); //構建我們的代理對象 Instrumentation evilInstrumentation = new InstrumentationProxy(mInstrumentation); //通過反射,換掉字段,注意,這裡是反射的代碼,不是Instrumentation裡面的方法 mInstrumentationField.set(currentActivityThread, evilInstrumentation); //做個標記,方便後面查看 Log.i(TAG, "has go in MyApplication attachContext method"); } }
package com.example.hookstartactivity; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.TextView; public class MainActivity extends ActionBarActivity { public static final String TAG = "MainActivity"; public TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView)findViewById(R.id.start); tv.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { try { Intent intent = new Intent(MainActivity.this, SecondActivity.class); Bundle bundle = new Bundle(); Log.i(TAG, "-------------------------------->"); Log.i(TAG, "startActivity before"); Log.i(TAG, "-------------------------------->"); startActivity(intent, bundle); Log.i(TAG, "-------------------------------->"); Log.i(TAG, "startActivity after"); Log.i(TAG, "-------------------------------->"); } catch (Exception e) { e.printStackTrace(); } } } ); } }
package com.example.hookstartactivity; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; public class SecondActivity extends ActionBarActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); } }
pidcat.py 包名就可以非常方便看的日志找bug了。
圖片的拖拉功能是處理圖片進一個有用且常用的功能,由於手機屏幕尺寸的限制,往往無法在手機上一次性的顯示一張比較大的圖片,也就是 說,我們在手機上一次性只能看到圖片的一部分,
這幾天被AsyncTask虐得不行,在此總結下 首先: AsyncTask的參數介紹 在開發Android移動客戶端的時候往往要使用多線程來進行操作,我們通常會
AlphaAnimation:透明度(alpha)漸變效果,對應< alpha/>”標簽。 TranslateAnimation:位移漸變,需要
概述關於Android ColorFilter 和 Tint之間的關系一直混淆不清。兩者均是對顯示的圖片進行著色或者過濾。 ColorFilter: 色彩過濾 Tint: