android的helloworld工程目录学习


Android工程的主要目录有src、gen、Android X.X、bin、res等文件夹。


1.     Src文件夹


Src文件夹包含java源文件(.java),如下图:

android的helloworld工程目录学习_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生命周期的开始,如下图:

android的helloworld工程目录学习_android_02

图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文件夹

android的helloworld工程目录学习_xml_03 

图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文件,先来看我们创建工程时的图:

android的helloworld工程目录学习_android_04

图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

 android的helloworld工程目录学习_java_05

图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文件夹

android的helloworld工程目录学习_xml_06

图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里。

 android的helloworld工程目录学习_java_07

图7


5.     assets文件夹

包含应用系统需要使用到的诸如mp3、视频类的文件,但HelloWorld工程下的assets是空文件夹


6.     bin文件夹

二进制文件,编译过后的文件,运行应用之后才在\bin\dexedLibs文件夹下生成可执行文件。


7.     libs文件夹

第三方的jar文件,比如android-support-v4.jar,即引用第三方的代码。


8.     res文件夹

android的helloworld工程目录学习_xml_08

图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>


后面再来详细学习这个文件。