认识Android编程各个文件之间的联系和使用方法,以及认识Activity文件结构的大体可以看下图:
代码在src中的.java文件中编辑,gen目录下有一个R.java的文件,这个文件存储res目录下各种资源文件的id号,在主文件java中调用该资源的时候直接调用id号即可,如 R.layout.main ,这个条目得打开R.java文件中查看,"R"对应R.java文件,"layout"对应R.java文件中的layout类,"main"对应layout类中的一个静态常量声明。
实际上res中的每一个文件都会在R.java中自动产生静态常量,这是res目录和assets目录最大的不同之处,这样做的好处不言而喻,对资源的修改不会对代码产生任何的影响,因为代码中使用的只是ID号码而已。
res目录中的前三个文件夹是存放图片资源的,而且通常情况下同一张图片要有三个版本二,高低中分辨率。
第四个文件夹是存放布局文件的,main.xml,一个Activity对应一个xml文件,而且每个Activity都要在AndroidMainfest.xml中注册一下。default.properties文件在学java的时候接触过,无非也是对对代码的可重复性使用和修改提供了方便而已。第一个Java Activity程序,会体现出这些文件之间的关系和使用。
下面程序任务:添加一个显示文本和一个按钮
对Activity的初步认识:就像一个窗口,能显示信息,又像一个容器,能容纳功能空间,如button,在程序角度上看,又像一个 类,可以和其他的类(Activity)发生联系。
创建Activity的要点:
一个Activity就是一个类,类名随意起,不过必须继承Activity这个父类。
需要复写onCreate()方法
每一个Activity都应该在AndroidManifest.xml文件中进行配置
为Activity添加必要的控件
整体文件代码预览:
MyActivity.java 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package geeker.MyActivity;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
public class MyActivity extends Activity {
//成员变量的声明
private TextView myTextView = null ;
private Button myButton = null ;
//重写OnCreate方法,会自动生成
public void onCreate(Bundle savedInstanceState) {
//调用父类方法,该句代码自动生成
super .onCreate(savedInstanceState);
//通过布局文件的id调用该Activity所使用的布局文件
setContentView(R.layout.main);
//通过findViewById()方法拿到布局文件中添加的控件
//不过在布局文件中添加控件的时候必须定义id号,
//如:android:id="@+id/myTextView"
myTextView = (TextView)findViewById(R.id.myTextView);
myButton = (Button)findViewById(R.id.myButton);
//向控件上制定显示文字
myTextView.setText( "This is my first Activity !" );
myButton.setText( "MY FIRST BUTTON" );
}
}
|
main.xml 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<? xml version = "1.0" encoding = "utf-8" ?>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
>
< TextView
android:id = "@+id/myTextView"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
/>
< Button
android:id = "@+id/myButton"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
/>
</ LinearLayout >
|
R.jar 文件该文件自动生成,不要自己改动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/* AUTO-GENERATED FILE. DO NOT MODIFY.
*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/
package geeker.MyActivity;
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int icon= 0x7f020000 ;
}
public static final class id {
public static final int myButton= 0x7f050001 ;
public static final int myTextView= 0x7f050000 ;
}
public static final class layout {
public static final int main= 0x7f030000 ;
}
public static final class string {
public static final int app_name= 0x7f040001 ;
public static final int hello= 0x7f040000 ;
}
}
|
其实走一遍添加Button的流程就明白各个文件间的联系了:
1. 先打开main.xml文件,加一个button按钮的布局
1
2
3
4
5
|
< Button
android:id = "@+id/myButton"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
/>
|
2. 其实上一步完成后,编译运行已经能看到一个Button按钮了,但是我想在按钮上添加文字以说明该按钮的作用,在java中的程序为 :
Button bt = new Button();
bt.setText("MY FIRST BUTTON");
那么在Android程序中如何在.java源文件中拿到刚才在main.xml中添加的控件呢?
基于这个目的,在main.xml文件中加了此句:android:id="@+id/myButton",这一句使得R.java文件中多了一个叫id的类,该控件的id号就在这个类中出现了,这样做为了方便.java文件中的调用。
实际上如果不加上一句,该控件是不会在R.java文件中产生id号码的,因为只有在res目录中添加文件才会自动在R.java中产生id号,而添加一个控件只是在一个资源文件中做修改而已,所以不会自动产生id号。
我们可以看一下R.java文件中自动产生的ID代码:
1
2
3
4
|
public static final class id {
public static final int myButton= 0x7f050001 ;
public static final int myTextView= 0x7f050000 ;
}
|
然后在.java文件中就可通过getViewById()方法拿到控件了。
拿到控件之后就可以像java程序中一样进行相关操作了,代码如:
1
2
3
|
private Button myButton = null ;
myButton = (Button)findViewById(R.id.myButton);
myButton.setText( "MY FIRST BUTTON" );
|
实际上这个流程只体现了xml文件和R.java文件之间的联系(通过该句:android:id="@+id/myButton),以及.java与R.java之间的联系(通过该句:findViewById(R.id.myTextView) )。补充一下其他文件关系的代码体现:
MyActivity.java文件与Main.xml文件的联系时通过MyActivity.java文件中的setContentView(R.layout.main);体现的,因为一个Activity文件要对应一个布局文件。
MyActivity.java文件与AndroidManifest.xml文件之间的联系时通过AndroidManifest.xml文件中的。
1
2
3
4
5
6
7
|
< activity android:name = ".MyActivity"
android:label = "@string/app_name" >
< intent-filter >
< action android:name = "android.intent.action.MAIN" />
< category android:name = "android.intent.category.LAUNCHER" />
</ intent-filter >
</ activity >
|
来体现的,这也说明了Activity创建的关键点之一:每一个Activity都应该在AndroidManifest.xml文件中进行配置。
PS:获取Android的文件列表的方法
有的时候我们的程序需要去对android的指定目录或者全局目录进行遍历获取其中的文件,但是获取文件的时候可能会遇到无法列出文件夹中的文件的问题,这就是我出现的问题,对于某个子文件夹进行获取listFiles()的时候返回为NULL,也就是不允许列出文件夹中内容。这个是由于android中的安全机制的缘故,由于android继承了Linux系统的传统,对于某个特定的目录有用户的权限,一共分为三种--可读,可写,可执行;虽然说我们可以设置某个特定的目录的权限,但是对于目录里面的子目录和子文件都可以进行权限的设置,也就是说出了根目录权限之外,子目录本身的权限也决定了子目录可否访问,这一点我们需要清楚了解,所以我们在判断完了是否是目录之外,我们还需要在进行listFiles()获取File[]数据后判断获取的数组是否为空,如果为空的话,文件夹是不可访问的。样例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
package net.nowamagic.file;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.util.Log;
/**
* @author
* function 用于扫描SD卡上的文件
*
*/
public class FileScan {
private static final String TAG = "FileScan" ;
public HashMap<String, String> getMusicListOnSys(File file) {
//从根目录开始扫描
Log.i(TAG, file.getPath());
HashMap<String, String> fileList = new HashMap<String, String>();
getFileList(file, fileList);
return fileList;
}
/**
* @param path
* @param fileList
* 注意的是并不是所有的文件夹都可以进行读取的,权限问题
*/
private void getFileList(File path, HashMap<String, String> fileList){
//如果是文件夹的话
if (path.isDirectory()){
//返回文件夹中有的数据
File[] files = path.listFiles();
//先判断下有没有权限,如果没有权限的话,就不执行了
if ( null == files)
return ;
for ( int i = 0 ; i < files.length; i++){
getFileList(files[i], fileList);
}
}
//如果是文件的话直接加入
else {
Log.i(TAG, path.getAbsolutePath());
//进行文件的处理
String filePath = path.getAbsolutePath();
//文件名
String fileName = filePath.substring(filePath.lastIndexOf( "/" )+ 1 );
//添加
fileList.put(fileName, filePath);
}
}
}
|