android的helloworld工程目录学习
Android工程的主要目录有src、gen、Android X.X、bin、res等文件夹。
1. Src文件夹
Src文件夹包含java源文件(.java),如下图:
图1
创建工程时,默认创建Activity对应的源代码文件为MainActivity.java,对应的类为名MainActivity,由上图可知MainActivity.java导入了很多类。
下面MainActivity类的定义:
public class MainActivityextends ActionBarActivity {
MainActivity(派生类/子类)继承自ActionBarActivity(父类)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, newPlaceholderFragment())
.commit();
}
}
(1)重写了父类的onCreate方法.
该方法是在Activity创建时被系统调用,是一个Activity生命周期的开始,如下图:
图2
(2)super.onCreate(savedInstanceState)
就是调用父类的onCreate构造函数,savedInstanceState是保存当前Activity的状态信息。
(3)setContentView(R.layout.activity_main)
此办法使用\res\layout\activity_main.xml文件定义的界面布局作为用户界面,此文件内容如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"//该组件的唯一标示符为container
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.helloworld.MainActivity"
tools:ignore="MergeRootFrame"/>
(4)Bundle savedInstanceState
从字面上看savedInstanceState,是保存实例状态的。实际上,savedInstanceState也就是保存Activity的状态的。那么,savedInstanceState中的状态数据是从何处而来的呢?下面我们介绍Activity的另一个方法saveInstanceState。
onsaveInstanceState方法是用来保存Activity的状态的。当一个Activity在生命周期结束前,会调用该方法保存状态。这个方法有一个参数名称与onCreate方法参数名称相同。如下所示:
public void onSaveInstanceState(BundlesavedInstanceState){
super.onSaveInstanceState(savedInsanceState);
}
在实际应用中,当一个Activity结束前,如果需要保存状态,就在onsaveInstanceState中,将状态数据以key-value的形式放入到savedInstanceState中。这样,当一个Activity被创建时,就能从onCreate的参数savedInsanceState中获得状态数据。
状态这个参数在实现应用中有很大的用途,比如:一个游戏在退出前,保存一下当前游戏运行的状态,当下次开启时能接着上次的继续玩下去。再比如:电子书程序,当一本小说被阅读到第199页后退出了(不管是内存不足还是用户自动关闭程序),当下次打开时,读者可能已忘记了上次已阅读到第几页了,但是,读者想接着上次的读下去。如果采用saveInstallState参数,就很容易解决上述问题。
(5)添加一个fragment到FrameLayout中。
getSupportFragmentManager().beginTransaction()
.add(R.id.container, newPlaceholderFragment())
.commit()
把new PlaceholderFragment()这个fragment添加到R.id.container这个FrameLayout中。
Activity中使用getSupportFragmentManager()获取FragmentManager,之后调用beginTransaction去创建一个FragmentTransaction对象, 再调用add()方法即可添加一个fragment。 在activity中可以使用同一个FragmentTransaction对象去执行多个fragment事务,当做这样操作时,必须调用commint()方法。
@Override
public boolean onCreateOptionsMenu(Menu menu){
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
(1) getMenuInflater().inflate(R.menu.main, menu)
getMenuInflater()的函数用来返回Activity的MenuInflater,并通过MenuInflater对象来设置menu XML里的menu作为该Activity的菜单
@Override
public boolean onOptionsItemSelected(MenuItemitem) {
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing asimple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public ViewonCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView =inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
2. gen文件夹
图3
由上图可知BuildConfig.java和R.java都是自动生成的,不能修改,BuildConfig.java是调试(Debug)时用的,一般不管,而且R.java是由AAPK工具生成的,但我发现采用V22.3.0的ADT新建HelloWorld工程的R.java内容较少,但V22.6.2版本的就非常多和全面。
下面以一个简单的R.java文件来学习
public final classR {
public static final class attr {
}
public static final class drawable {
public static final intic_launcher=0x7f020057;
}
public static final class layout {
public static final intactivity_main=0x7f030018;
public static final intfragment_main=0x7f030019;
}
public static final class string {
public static final intapp_name=0x7f040001;
public static final inthello=0x7f040000;
}
}
这里的R应该就是resource的简称,这个R.java文件中有attr、drawable、layout和string等四个静态内部类,每个静态内部类分别对应着一种资源,比如layout静态内部类对应res\layout文件夹下的activity_main.xml和fragment_main.xml文件,先来看我们创建工程时的图:
图4
再来看activity_main.xml文件的内容:
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.helloworld.MainActivity"
tools:ignore="MergeRootFrame" />
接着看fragment_main.xml文件的内容:
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.helloworld.MainActivity$PlaceholderFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"/>
</RelativeLayout>
可见activity_main是Activity的容器,而fragment_main定义的相对布局是放在此容器中。
由于目前【drawable-*dpi】目录下都只有ic_launcher.png一个图片文件,因此此时不同详述的同名的ic_launcher.png文件在drawable内部类总只有一个icon属性。如果我们在【drawable-*dpi】目录下再添加一幅图片,则内部类中会自动的添加一个icon属性。
PS:添加资源的命名规则:资源文件只能以小写字母和下划线做首字母,随后的名字中只能出现 [a-z0-9_.] 这些字符,否则R.java文件不会自动更新,并且eclipse会提示错误。
理解了R.java文件中内容的来源,即当开发者在res/目录中任何一个子目录中添加相应类型的文件之后,ADT会在R.java文件中相应的匿名内部类中国自动生成一条静态int类型的常量,对添加的文件进行索引。如果在layout目录下再添加一个新的界面,那么在public static final class layout中也会添加相应的静态int常量。相反当我们在res目录下删除任何一个文件,其在R.java中对应的记录会被ADT自动删除。
R.java文件按除了有自动标示资源的索引功能之外,还有另外一个主要的功能,如果res目录中的某个资源在应用中没有被使用到,在该应用被编译的时候系统就不会把对应的资源编译到该应用的APK包中,这样可以节省Android手机的资源。
3. Android4.4.2
图5
可知此Android 4.4.2 文件夹下包含android.jar文件,这是一个Java 归档文件,其中包含构建应用程序所需的所有的Android SDK 库(如Views、Controls)和APIs。通过android.jar将自己的应用程序绑定到Android SDK和Android Emulator,这允许你使用所有Android的库和包,且使你的应用程序在适当的环境中调试。例如上面的MainActivity.java源文件中(见图1) 的:
…
importandroid.os.Bundle;
importandroid.view.LayoutInflater;
importandroid.view.Menu;
…
这就是从android.jar导入包。
4. androidprivate libraries和android dependencies文件夹
图6
从ADT16开始,Android项目中多了一个名为“Android Dependencies”的库应用文件夹,这是ADT的第三方库新的引用方式。
当你需要引用第三方库时,只需在项目中新建一个名为"libs"的文件夹,然后将所有第三方包拷贝到该目录下。当eclipse启动时,ADT就会自动帮你完成库的引用,而不需要像以前一样自己Build Path,也不再需要Referenced Libraries了。
ADT 22中新增了Export,你会发现新增了Android Private Libraries库,所有的第三方JAR包引入都被放入了Android Private Libraries
ADT21的时候,库工程生成的jar和主工程的第三方jar都都归纳为Android Dependencies,而ADT22是自动将JAR分成Android Private Libraries和Android Dependencies两类,ADT21不需要勾选Export就能自动将所有引用的JAR包导出并打包到APK,而ADT22则给开发人员选择权限,让开发人员自己决定哪些包要导出到APK里。
图7
5. assets文件夹
包含应用系统需要使用到的诸如mp3、视频类的文件,但HelloWorld工程下的assets是空文件夹
6. bin文件夹
二进制文件,编译过后的文件,运行应用之后才在\bin\dexedLibs文件夹下生成可执行文件。
7. libs文件夹
第三方的jar文件,比如android-support-v4.jar,即引用第三方的代码。
8. res文件夹
图8
资源目录,包含你项目中的资源文件并将编译进应用程序。向此目录添加资源时,会被R.java自动记录。新建一个项目,res目录下会有四个子目录:drawabel、layout、menuvalues。
drawabel-xdpi:包含一些你的应用程序可以用的图标文件(*.png、*.jpg)
layout:界面布局文件(.xml)与WEB应用中的HTML类同,其中fragment_main.xml文件的内容见上面的描述。
Menu:是菜单的内容。
values:软件上所需要显示的各种文字。可以存放多个*.xml文件,还可以存放不同类型的数据。比如dimens.xml、strings.xml、styles.xml。
9. AndroidManifest.xml文件
项目的总配置文件,记录应用中所使用的各种组件。这个文件列出了应用程序所提供的功能,在这个文件中,你可以指定应用程序使用到的服务(如电话服务、互联网 服务、短信服务、GPS服务等等)。另外当你新添加一个Activity的时候,也需要在这个文件中进行相应配置,只有配置好后,才能调用此 Activity。AndroidManifest.xml将包含如下设置:application permissions、Activities、intent filters等。
AndroidManifest.xml的内容如下:
<?xmlversion="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.helloworld"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="19"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.helloworld.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
后面再来详细学习这个文件。