Android应用开发的一般文件组织结构讲解
认识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 文件
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 文件
<?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 文件该文件自动生成,不要自己改动
/* 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按钮的布局
<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代码:
public static final class id { public static final int mybutton=0x7f050001; public static final int mytextview=0x7f050000; }
然后在.java文件中就可通过getviewbyid()方法拿到控件了。
拿到控件之后就可以像java程序中一样进行相关操作了,代码如:
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文件中的。
<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[]数据后判断获取的数组是否为空,如果为空的话,文件夹是不可访问的。样例代码如下:
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); } } }
上一篇: Shiro集成Spring之注解示例详解