編輯:關於Android編程
啟動模式一共有四種,分別是 standard、singleTop、singleTask 和singleInstance,可以在AndroidManifest.xml中通過給activity標簽指定android:launchMode 屬性來選擇啟動模式。
1、standard模式
standard 是活動默認的啟動模式,在不進行顯式指定的情況下,所有活動都會自動使用這種啟動模式。 Android 是使用返回棧來管理活動的,在 standard 模式(即默認情況)下,每當啟動一個新的活動,它就會在返回棧中入棧,並處於棧頂的位置。對於使用standard 模式的活動,系統不會在乎這個活動是否已經在返回棧中存在,每次啟動都會創建該活動的一個新的實例。下面寫代碼來驗證一下:
首先在Androidmanifest文件中的activity標簽設置FirstActivity的啟動模式為standard:
在OnCreate方法中打印當前棧頂活動的ID,另外加入一個Button,並設置其的監控事件為啟動FirstActivity:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); Log.d("FirstActivity",this.toString()); first_btn = (Button) findViewById(R.id.first_btn); first_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(FirstActivity.this,FirstActivity.class)); } }); }
運行項目,連續點擊兩次Button,打印信息是這樣的:
可見三次Activity的ID都不同,所以要退出程序也要按三次back鍵。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPs/Cw+a4+LP2c3RhbmRhcmQgxKPKvbXE1K3A7cq+0uLNvKO6PGJyIC8+DQo8aW1nIGFsdD0="這裡寫圖片描述" src="/uploadfile/Collfiles/20161017/201610170925021544.png" title="\" />
2、singleTop模式
當活動的啟動模式指定為 singleTop,在啟動活動時如果發現返回棧的棧頂已經是該活動,則認為可以直接使用它,不會再創建新的活動實例。
代碼:
同樣,先設置活動的啟動模式為singleTop:
其它先不改變,運行項目,打印信息:
這時無論你點擊多少次按鈕,依然不會出現新的打印信息,因為目前 FirstActivity已經處於返回棧的棧頂,每當想要再啟動一個 FirstActivity時都會直接使用棧頂的活動,因此 FirstActivity 也只會有一個實例,僅按一次 Back 鍵就可以退出程序。
不過當 FirstActivity 並未處於棧頂位置時,這時再啟動 FirstActivity,還是會創建新的實例的。下面我們來實驗一下,修改 FirstActivity 中 onCreate()方法的代碼,如下所示:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); Log.d("FirstActivity",this.toString()); first_btn = (Button) findViewById(R.id.first_btn); first_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(FirstActivity.this,SecondActivity.class)); } }); }
創建SecondActivity,加入Button並設置其點擊事件為啟動FirstActivity:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Log.d("SecondActivity",this.toString()); second_btn = (Button) findViewById(R.id.second_btn); second_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(SecondActivity.this, FirstActivity.class); startActivity(intent); } }); }
現在重新運行程序,在 FirstActivity 界面點擊按鈕進入到 SecondActivity,然後在 SecondActivity 界面點擊按鈕,又會重新進入到 FirstActivity。
打印信息:
可以看到系統創建了兩個不同的 FirstActivity 實例,這是由於在 SecondActivity 中再次啟動 FirstActivity 時,棧頂活動已經變成了 SecondActivity,因此會創建一個新的 FirstActivity實例。現在按下 Back 鍵會返回到 SecondActivity,再次按下 Back 鍵又會回到 FirstActivity,再按一次 Back 鍵才會退出程序。
下面給出singleTop的原理示意圖:
3、singleTask模式
當活動的啟動模式指定為 singleTask,每次啟動該活動時系統首先會在返回棧中檢查是否存在該活動的實例,如果發現已經存在則直接使用該實例,並把在這個活動之上的所有活動統統出棧,如果沒有發現就會創建一個新的活動實例。
代碼:
同樣是設置FirstActivity的啟動模式為singleTask:
然後在 FirstActivity 中添加 onRestart()方法,並打印日志:
@Override protected void onRestart() { super.onRestart(); Log.d("FirstActivity", "onRestart"); }
最後在 SecondActivity 中添加 onDestroy()方法,並打印日志:
@Override protected void onDestroy() { super.onDestroy(); Log.d("SecondActivity", "onDestroy"); }
現在重新運行程序,在 FirstActivity 界面點擊按鈕進入到SecondActivity,然後在SecondActivity 界面點擊按鈕,又會重新進入到 FirstActivity。
查看 LogCat 中的打印信息:
從打印信息可以看出,在 SecondActivity 中啟動 FirstActivity 時,會發
現返回棧中已經存在一個 FirstActivity 的實例,並且是在SecondActivity 的下面,於是SecondActivity 會從返回棧中出棧,而 FirstActivity 重新成為了棧頂活動,因此 FirstActivity的 onRestart()方法和 SecondActivity 的 onDestroy()方法會得到執行。現在返回棧中應該只剩下一個 FirstActivity 的實例了,按一下 Back 鍵就可以退出程序。
singleTask 模式的原理示意圖:
4、singleInstance模式
指定為 singleInstance 模式的活動會啟用一個新的返回棧來管理這個活動(其實如果 singleTask 模式指定了不同的 taskAffinity,也會啟動一個新的返回棧)。那麼這樣做有什麼意義呢?想象以下場景,假設我們的程序中有一個活動是允許其他程序調用的,如果我們想實現其他程序和我們的程序可以共享這個活動的實例,應該如何實現呢?使用前面三種啟動模式肯定是做不到的,因為每個應用程序都會有自己的返回棧,同一個活動在不同的返回棧中入棧時必然是創建了新的實例。而使用singleInstance 模式就可以解決這個問題,在這種模式下會有一個單獨的返回棧來管理這個活動,不管是哪個應用程序來訪問這個活動,都共用的同一個返回棧,也就解決了共享活動實例的問題。
代碼:
同樣設置Activity啟動模式為singleInstance:
修改 FirstActivity 中onCreate()方法的代碼:在 onCreate()方法中打印了當前返回棧的 id
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); Log.d("FirstActivity","Task id is " + getTaskId()); first_btn = (Button) findViewById(R.id.first_btn); first_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(FirstActivity.this,SecondActivity.class)); } }); }
修改 SecondActivity 中 onCreate()方法的代碼:同樣在 onCreate()方法中打印了當前返回棧的 id,然後又修改了按鈕點擊事件的代碼,用於啟動 ThirdActivity。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Log.d("SecondActivity","Task id is " + getTaskId()); second_btn = (Button) findViewById(R.id.second_btn); second_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(SecondActivity.this, ThridActivity.class); startActivity(intent); } }); }
最後修改 ThirdActivity 中 onCreate()方法的代碼:仍然是在 onCreate()方法中打印了當前返回棧的 id。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_thrid); Log.d("ThirdActivity", "Task id is " + getTaskId()); }
現在重新運行程序,在 FirstActivity界面點擊 按鈕進入 到 SecondActivity, 然 後 在 SecondActivity 界 面 點擊按鈕進入 到ThirdActivity。
查看 LogCat 中的打印信息:
可以看到, SecondActivity 的 Task id 不同於 FirstActivity 和 ThirdActivity,這說明SecondActivity 確實是存放在一個單獨的返回棧裡的,而且這個棧中只有 SecondActivity 這一個活動。然後我們按下 Back 鍵進行返回,你會發現 ThirdActivity 竟然直接返回到了FirstActivity,再按下 Back 鍵又會返回到 SecondActivity,再按下 Back 鍵才會退出程序,這是為什麼呢?其實原理很簡單,由於FirstActivity 和 ThirdActivity 是存放在同一個返回棧裡的, 當在ThirdActivity 的界面按下 Back 鍵, ThirdActivity 會從返回棧中出棧,那麼 FirstActivity 就成為了棧頂活動顯示在界面上,因此也就出現了從 ThirdActivity 直接返回到 FirstActivity 的情況。然後在 FirstActivity 界面再次按下 Back 鍵,這時當前的返回棧已經空了,於是就顯示了另一個返回棧的棧頂活動,即 SecondActivity。最後再次按下 Back 鍵,這時所有返回棧都已經空了,也就自然退出了程序。
singleInstance 模式的原理示意圖:
開門見山,添加水印的方法非常簡單,其實就只有3個步驟:1、載入原始圖片2、載入水印圖片3、保存帶有水印的圖片實現的原理就是:獲取原始圖片的寬高,然後,新建一個同樣寬高的b
由於項目上的需要側滑條目展示收藏按鈕,記得之前代碼家有寫過一個厲害的開源控件 AndroidSwipeLayout 本來准備直接拿來使用,但是看過 issue 發現現在有
GridView用於在界面上按行、列分布顯示多個組件。GridView和ListView有共同父類:AbsListView。GridView與Lis
android開發,除了使用原生態的開發方式之外,還可以使用java+html+javascript混合開發的方式來開發,這樣可以節省大量的開發時間,同時還可以使不同設備