闲来无事,玩玩andorid,目的是希望做个小程序,方便清理手机自带相机的隐藏文件。
玩这个,自然是先准备编译环境。之前JDK和eclipse都已经安装好了,因而理论上只要安装andorid SDK 及ADT就可以了,然而后两者所在的网站被墙了。于是随便从网上百度了一个ADT包玩玩。
编译环境玩起来后,按照网上的代码写了个hello andorid!其代码很简单,即在java源文件中,增加两行:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = new TextView(this);
tv.setText("Hello, Android");
setContentView(tv); /* 此行代码为整个错误埋下了隐患*/
}
想看到这个Hello, Android,还需要一个AVD,即andorid virtual device,也就是不直接连接某个版本的手机,而是模拟出来一个。百度出的ADT开发工具里面自带了一些google 机器的AVD,随便选了一个,配置了下,在配置时,需要根据自己PC的实际硬件资源情况,比如PC总共2G内存,而AVD默认要1.9G内存,则创建AVD的时候肯定失败了。AVD创建后,启动比较慢,启动后,就相当于AVD和开发环境建立了一个链接,开发环境生成的APK包,可以上传到AVD上安装运行测试。
经过上述准备后,运行上面的代码,就可以在AVD设备上显示出 Hello,Android了。
由于初次玩,代码都是拷贝的,于是虽则只有三行代码也埋下了隐患。
继续在同一个工程中玩,类似PC下面用VC开发视图程序。简单的讲,图形界面包括:一个显示行,两个按钮。按钮操作后,显示行的内容会跟着改变。代码也基本是网上学习到的。
public class MainActivity extends Activity {
int counter;
Button sub,add;
TextView vwDisplay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = new TextView(this);
tv.setText("Hello, Android");
setContentView(tv);
counter=0;
sub = (Button) findViewById(R.id.bsub);
add = (Button) findViewById(R.id.badd);
vwDisplay = (TextView) findViewById(R.id.vwtotal); /* 此处指针为空了!!!!!!!! */
if(null==add)
{
tv.setText("Hello, Android1");
setContentView(tv);
}
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
counter++;
vwDisplay.setText(" total is"+counter);
}
});
sub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
counter--;
vwDisplay.setText(" total is"+counter);
}
});
}
代码意图很简单,然而运行时报空指针了。红色部分确认,指针为空了。通过logcat也看到空指针了。
最后定位了,在做Hello Andorid时,增加了下面一句:
setContentView(tv);
虽然初玩,不了解这个函数的含义,但是猜想整个空指针的原因:
初始时,
setContentView(R.layout.activity_main);
参数为activity_main,而修改增加的add Button对象,是嵌入到activity_main对象中的。下面调用的find函数只有从activity_main对象中才能发现新增加的Button对象。
然后不幸,使用参数tv后,改变了当前对象指向,导致find不到add Button对象了。