http://blog.csdn.net/yanzi1225627/article/details/7802018這裏的問題我已經找到了答案.html
setContentView的祕密:eclipse
當activity 調用 setContentView() 時,Android 纔會去繪製 layout 上的各個元素,併爲其分配內存。只有分配了內存之後,才能繼續執行findViewById(); 才能獲得引用,否則獲得空引用。空引用意味着,後面使用相應變量時就會發生訪問的對象不存在的問題。當Activity從新setContentView()之後,那些以前繪製的控件,內存都被滅掉了。因此,如果經過setContentView 來達到畫面切換目的的,要注意從新繪製之後從新取得引用。ide
--------(參考:http://www.go2solo.net/2011/07/08/setcontentview%E7%9A%84%E7%A7%98%E5%AF%86.html函數
http://blog.csdn.net/simplty/article/details/7036773)佈局
什麼是LayoutInflater?this
LayoutInflater的做用就至關於findViewById,只不事後者是查找一些小的widget,如button、textview,而前者是查找layout文件下的.xml佈局文件。也就是說:LayoutInflater 把佈局xml文件引入成View對象,再經過setContentView(View view)方法來切換視圖。由於全部對View的修改都保存在View對象裏,因此,當切換回原來的view時,就能夠直接顯示原來修改後的樣子。這樣也 就解決了setContentView後還要findViewById的問題,由於這裏是實例化的view對象,經過這個view去 setContentView,並且還能有效保存切換頁面前的內容。spa
所以,我將程序修改爲這個樣子:.net
public class MainActivity extends Activity {
View layoutMain = null;
View layoutSecond = null;
Button btn_mainActivity = null;
Button btn_secondActivity;
boolean firstFlag = true;
long time = (long)0.0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = this.getLayoutInflater();
layoutMain = inflater.inflate(R.layout.activity_main, null);
layoutSecond = inflater.inflate(R.layout.activity_second, null);
setContentView(layoutMain);xml
btn_mainActivity = (Button)findViewById(R.id.btn_mainAc_1);
btn_mainActivity.setOnClickListener(new ButtonListen());htm
}
class ButtonListen implements OnClickListener{
public void onClick(View v) {
// TODO Auto-generated method stub
time = System.currentTimeMillis();
switch(v.getId()){
case R.id.btn_mainAc_1:
Jump2Second();
break;
case R.id.btn_secondA_1:
Jump2Main();
break;
default:
break;
}
}
}
public void Jump2Second(){
setContentView(layoutSecond);
long currTime = System.currentTimeMillis();
Toast.makeText(MainActivity.this,
"切換耗時:" +String.valueOf(currTime-time)+"毫秒",
Toast.LENGTH_SHORT).show();
if(firstFlag){
btn_secondActivity = (Button)findViewById(R.id.btn_secondA_1);
btn_secondActivity.setOnClickListener(new ButtonListen());
firstFlag = false;
}
}
public void Jump2Main(){
setContentView(layoutMain);
long currTime = System.currentTimeMillis();
Toast.makeText(MainActivity.this,
"切換耗時:" +String.valueOf(currTime-time)+"毫秒",
Toast.LENGTH_SHORT).show();
}
}
這裏要注意,firstFlag的使用,判斷是否第一次跳轉至second界面,若是是第一次的話則findViewById而後監聽,只須要綁定一次就 能夠了。並且這個綁定必須在跳轉函數裏,不能在onCreate方法裏。爲何呢?由於在onCreate方法裏 setContentView(layoutMain),系統只爲layoutMain裏的元素分配了內存,並無爲layoutSecond上的元素分 配內存,儘管這裏用view將其實例化對象裏。(這塊表述可能不許確,歡迎大神們指點)
總之,沒有setContentView(第二個界面)以前,第二個界面裏的元素雖然可以find到,eclipse沒有報錯,但由於沒有被分配內存,因此在onCreate這裏爲第二個界面綁定監聽是錯誤的!你運行的時候程序會直接掛掉。
記住:setContentView以後才爲佈局裏的元素分配內存,在未分配內存前對元素進行訪問時沒有意義的!!!