目录

第一章 准备工作

一、Android 系统架构

二、Android 开发特点

1、四大组件

2、系统控件丰富

3、SQLite数据库

4、多媒体功能强大

5、地理位置定位

三、日志工具的使用

第二章  活动(Activity)

一、活动基本操作

1.手动创建活动

2.创建和加载布局

3.活动的注册

4.Toast的使用

5.Menu的使用

6.销毁活动

二、Intent的使用

1.显式Intent

2.隐式Intent

3.传数据给下一个活动

4.返回数据个上一个活动

三、活动生命周期

1.返回栈

2.活动的状态

3.活动的3种生存期与7个回调方法

4、活动的回收

四、活动的启动模式

1.standard模式(标准模式)

2.singleTop模式(单顶模式)

3.singleTask模式(单任务模式)

4.singleInstance模式(单例模式)

五、开发小技巧

1.随时清楚当前运行的是哪一个活动

2.随时退出程序

3.启动活动的最佳写法

第三章 UI开发

一、常用控件

1.TextView



第一章 准备工作

一、Android 系统架构

        Linux内核层、系统运行库层、应用框架层、应用层

二、Android 开发特点

1、四大组件

        活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)、内容提供器(Content Provider)。

2、系统控件丰富

3、SQLite数据库

4、多媒体功能强大

5、地理位置定位

三、日志工具的使用

五个日志等级即对应的方法:

日志等级方法名
verboseLog.v()
debugLog.d()
infoLog.i()
warnLog.w()
errorLog.r()

方法的使用:

例如:Log.d(tag,msg); 其中tag一般传入当前类的类名,msg为想要具体打印的内容。

第二章  活动(Activity)

一、活动基本操作

1.手动创建活动

        活动创建界面中的“Generate Layout File”表示自动创建对应的布局文件,“Launcher Activity”表示将当前要创建的活动设置为项目的主活动,按实际需求勾选。

2.创建和加载布局

        布局文件在app/src/main/res/layout目录下,Android程序设计讲究逻辑和视图分离,所以每一个活动最好都要对应一个布局。

布局的加载:

@Override
protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_name);    //layout_name 为布局文件名
}

3.活动的注册

        所有活动都必须要在AndroidManifest.xml文件中的<application>标签内通过<activity>标签进行注册才能生效。如果是主活动,则还应在<activity>标签内加入<intent-filter>标签,并在里面添加声明:

<activity android:name=".ActivityName"
    android:lable="msg">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.categoty.LAUNCHER"/>
    </intent-filter>
</activity>

4.Toast的使用

        Toast即一个显示在屏幕底端的短时间提示信息。使用Toast首先要有弹出Toast的触发点,以按钮为例:

Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(
    new View.OnClickListener(){
        @Override
        public void onClick(View v){
            Toast.makeText(Activity_Name.this,"msg",Toast.LENGTH_SHORT).show();
        }
    }
);
//Activity_Name为当前类的类名
//msg为要显示的内容
//第三个参数为显示时长,Toast.LENGTH_SHORT或Toast.LENGTH_LONG

5.Menu的使用

        (1)创建:在res/menu文件夹(若没有menu 文件夹则手动在res文件夹里创建)里新建Menu resource file(假设命名为main),然后在main.xml文件中添加菜单项

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/item_name1"
        android:title="item1"/>
    <item
        android:id="@+id/item_name2"
        android:title="item2"/>
</menu>

id为菜单项的唯一标识符,title为菜单项的显示内容。

        (2)获取:在活动类中重写onCreateOptionsMenu()方法为当前活动添加菜单

@Override
public boolean onCreateOptionsMenu(Menu menu){
    getMenuInflater().inflate(R.menu.main,menu);//参数一为创建菜单的资源文件,参数二为onCreateOptionsMenu()方法中的参数
    return true;
}

        (3)相应菜单项:重写onOptionsItemSelected()方法

public boolean onOptionsItemSelected(MenuItem item){
    switch(item.getItemId){
    case R.id.item_name1:
        //逻辑操作
        break;
    case R.id.item_name2:
        //逻辑操作
        break;
    default:
    }
    return true;
}

6.销毁活动

        使用finish()方法。

二、Intent的使用

        Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅仅可以指明当前组件要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用于启动活动、启动服务以及发送广播等场景。

1.显式Intent

        使用构造方法Intent(Context packageContext,Class<?> cls);其中Context用于提供上下文,cls用于指定要启动的目标活动。

button.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(){
        Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
        startActivity(intent);
    }
});
//即在活动FirstActivity中点击button按钮启动活动SecondActivity;

2.隐式Intent

        在AndroidManifest.xml文件中的<activity>标签下配置<intent-filter>的内容,可以指定当前活动能够相应的action和category,

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="com.example.activitytest.ACTION_START"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="com.example.activitytest.MY_CATEGORY"/>
    </intent-filter>
</activity>

        只有当SecondActivity的<action>和<category>中的内容同时能够匹配Intent中指定的action和category时,SecondActivity才能响应该Intent,因此,FirstActivity中的Intent要指定相匹配的action 和 category,

button.setOnClickListener(
    new View.OnClickListener(){
        @Override
        public void onClick(View v){
            Intent intent = new Intent("com.example.activitytest.ACTION_START");
            intent.addCategory("android.intent.category.DEFAULT");
            intent.addCategory("com.example.activitytest.MY_CATEGORY");
            startActivity(intent);
        }
    }
);
//android.intent.category.DEFAULT是一种默认的category,这里可省略
//每个Intent只能指定一个action,但是可以同时指定多个category

        **其他隐式Intent的用法:

        使用隐式Intent还可以启动其他程序的活动,使Android多个应用程序之间的功能共享成为了可能。

        例如程序中需要打开一个网页(百度首页),则对intent进行如下操作:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDate(Uri.parse("http://www.baidu.com"));
startActivity(intent);

        我们也可以在<intent-filter>标签总配置一个<data>标签,用于精确地指定当前活动能够相应什么类型的数据,<data>标签的可配置内容如下:

        

android:scheme指定数据的协议部分
android:host指定数据的主机名部分
android:port指定数据的端口部分
android:path指定主机名和端口之后的部分
android:mimeType

指定可以处理的数据类型

        同样的,只有<data>标签中指定的内容与Intent中携带的Data完全一致时,当前活动才能够相应该Intent。

3.传数据给下一个活动

        实现的思路:Intent提供了一系列的putExtra()方法的重载,可以将我们想要传递的数据暂存到Intent中,启动另一个活动后,在从Intent中取出数据即可。

        例如:现在要从活动FirstActivity中传递数据到活动SecondActivity中显示出来.

则在FirstActivity中

button.setOnClickListener(
    new View.OnClickListener(){
        @Override
        public void onClick(View v){
            String data = "Hello SecondActivity!";
            Intent intent = new Intent(FirstActivity.this,SecondActivity.class);//显式Intent
            intent.putExtra("extra_data",data);//两个参数为一对键值对,参数一为键,参数二为值,键的目的是为了方便在目标活动中进行取值
            startActivity(intent);
        }
    }
);

在SecondActivity中

protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.second_layout);
    Intent intent = getIntent();//getIntent()方法用于获取启动本活动的Intent
    String data = intent.getStringExtra("extra_data");
    Log.d("SecondActivity",data);
}

活动SecondActivity中成功获取了活动FirstActivity传递过来的数据extra_data。

4.返回数据个上一个活动

        一个活动结束时也可以向上一个活动返回数据,要实现这一功能需要使用startActivityForResult()方法来启动活动,则该启动的活动在销毁时能够返回一个结果给上一个活动。

        例如:在FirstActivity中启动SecondActivity,SecondActivity销毁后返回一个数据给FirstActivity.

则在FirstActivity中:

@Override
public void onClick(){
    Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
    startActivityForResult(intent,1);
}//startActivityForResult()方法包含两个参数,参数一还是含“意图”的Intent,参数二是请求码,用于在之后的回调处理中判断数据来源

在SecondActivity中:

        结束一个活动可以通过设置特定按钮来实现,也可以通过点击手机“返回”按钮来实现,以下分情况讨论。

1)设置特定按钮:

button2.setOnClickListener(
    new View.OnClickListener(){
        @Override
        public void onClick(View v){
            Intent intent = new Intent();//无意图,单纯存数据
            intnet.putExtra("data_return","Hello FirstActivity!");
            setResult(RESULT_OK,intent);
            finish();//销毁当前活动
        }
    }
);
//setResult()方法专门用于向上一个活动返回数据,两个参数,参数一为处理结果(RESULT_OK或RESULT_CANCELED),参数二为带数据的Intent

2)“返回”键

@Override
public void onBackPressed(){
    Intent intent = new Intent();
    intent.putExtra("data_return","Hello FirstActivity!");
    setResult(RESULT_OK,intent);
    finish();
}

        由于使用startActivityForResult()方法来启动SecondeActivity,则SecondeActivity被销毁后,会回调FirstActivity中的onActivityResult()方法来处理SecondActivity回传的数据,因此重写FirstActivity中的onActivityResult()方法:

@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
    switch(requestCode){
        case 1:
            if(resultCode == RESULT_OK){
                String returned_data = data.getStringExtra("data_return");
                Log.d("FirstActivity",return_data);
            }
            break;
        default:
    }
}
//参数说明:
参数一:requestCode(请求码):即启动活动时startActivityForResult()方法中传入的参数二,因为
有可能通过FirstActivity活动启动多个活动,且这些活动销毁后都需要返回数据,而这些活动销毁后返回
的数据全部都是由FirstActivity活动中的onActivityResult()方法来接收处理,因此onActivityResult()方
法中需要一个请求码来辨别接收的数据来源,所以在启动活动的时候我们也需要在startActivityForResult()方
法中传入一个请求码;
参数二:resultCode(处理结果):即活动销毁前向上返回数据的setResult()方法中的参数一,取值
RESULT_OK或RESULT_CANCELED,方便处理数据时分情况处理;
参数三:data:即携带返回数据的Intent。

三、活动生命周期

1.返回栈

        返回栈用于存放一个任务的所有活动。Android通过任务来管理活动,一个任务就是一组存放在栈里的活动的集合。

2.活动的状态

        活动在生命周期内存在4种状态:运行、暂停、停止、销毁。

状态位置可见性
运行状态栈顶可见
暂停状态非栈顶可见
停止状态非栈顶不可见
销毁状态出栈不可见

3.活动的3种生存期与7个回调方法

回调方法说明对应状态
onCreate()创建活动
onStart()变为可见
onResume()栈顶可交互运行状态
onPause()非栈顶可见暂停状态
onStop()非栈顶不可见停止状态
onDestroy()销毁活动销毁状态
onRestart()重启活动停止转运行
生存期起始方法结束方法说明
完整生存期onCreate()onDestroy()
可见生存期onStart()onStop()
前台生存期onResume()onPause()可交互

        当一个活动初次创建且可交互时,会依次执行onCreate(),onStart(),onResume()三个方法;当其他活动把它完全遮挡住时,会依次执行onPause(),onStop()方法,按“返回”键返回第一个活动时,会依次执行onRestart(),onStart(),onResume()三个方法;当其他活动没有完全遮挡住它时,只执行onPause()方法,按“返回”键后也只执行onResume()方法;再按“返回”键销毁第一个活动时,会依次执行onPause(),onStop(),onDestroy()三个方法。

4、活动的回收

        当一个活动进入停止状态后,可能会由于内存资源紧张而被系统回收,但是当要返回该活动再次进入运行状态时就不会执行onRestart()方法了,而是执行onCreate()方法再创建一次。

        然而一个活动可能会存在临时数据与状态,如果重新创建这些数据与状态都会丢失,严重影响用户体验,可使用onSaveInstanceState()回调方法解决次问题。

        在有可能被回收的活动中重写onSaveInstanceState()方法,若活动被回收,则回收之前会调用该方法,把临时数据保存到Bundle中,

@Override
proteced void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    String tempData = "Something you want save.";
    outState.putString("data_key",temData);
}
//参数说明:
Bundle型参数用于保存临时数据,通过一系列方法实现,
如putString(),putInt()等,这些方法又包含两个参数,
参数一是键,参数二是值。

        在活动创建方法onCreate()中,携带了Bundle参数,该参数就是用于恢复数据的,通常该参数值为null,只有在活动被系统回收前通过onSaveInstanceState()方法来保存数据的情况下,Bundle才会携带有数据,此时只需要使用相应的方法取出数据即可,

@Override
protected void onCreate(Bundle SavedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if(savedInstanceState!=null){
        String tempDate = savedInstanceState.getString("data_key");
        .........
    }
}

四、活动的启动模式

        可在AndroidMenifest.xml文件中的<activity>标签中通过android:launchMode属性来指定活动的启动模式,活动的启动模式有standard、singleTop、singleTask、singleInstance四种,可根据实际需求选择使用。

1.standard模式(标准模式)

        默认的标准启动模式。standard模式下,对于一个活动,无论是否已经有它的实例在返回栈中,每次启动都会创建该活动的一个新的实例并入栈到栈顶。

2.singleTop模式(单顶模式)

        在singleTop模式下,对于一个活动,如果它已经在栈顶,则再次启动该活动时不会再创建新的实例,而是直接使用栈顶的活动;但如果不在栈顶,则还是会创建一个新的实例入栈到栈顶。

3.singleTask模式(单任务模式)

        在singleTask模式下,要启动一个活动时,若返回栈中已经有该活动的实例,则会把该活动之上的所有活动出栈,然后直接使用该活动实例;若返回栈中还没有该活动实例,则会在栈顶新创建一个活动实例。

4.singleInstance模式(单例模式)

        在singleInstance模式下,该活动会由一个新的返回栈来管理,可实现多程序共享活动实例功能。该模式下活动的销毁过程也不同,会先从栈顶到栈底依次销毁返回栈中的活动,返回栈中的活动全部销毁之后,才会再按顺序销毁共享返回栈(被指定为singleInstance模式的活动所在的返回栈,这是我自己给它起的暂时的名字)中的活动。

五、开发小技巧

1.随时清楚当前运行的是哪一个活动

        让项目中所有的活动类不再继承自AppCompatActivity类,而是继承自我们自己新创建的一个类BaseActivity,BaseActivity类代码如下:

public class BaseActivity extends AppcompatActivity{
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        Log.d("BaseActivity",getClass().getSimpleName());
    }
}

2.随时退出程序

        当返回栈中有较多活动时,想要退出程序会非常麻烦。可以创建一个活动管理器类ActivityCollector,通过一个专门的集合类List<Activity>来对所有的活动进行管理。

public class ActivityCollector{
    public static List<Activity> activities = new ArrayList<>();
    
    public static void addActivity(Activity activity){
        activities.add(activity);
    }

    public static void removeActivity(Activity activity){
        activities.remove(activity);
    }

    public static void finishAll(){
        for(Activity activity:activities){
            if(!activity.ifFinishing()){
                activity.finish();
            }
        }
        activities.clear();
    }
}

        然后在BaseActivity类中重写的onCreate()方法中执行ActivityCollector.addActivity(this);语句,在重写的onDestroy()方法中执行ActivityCollector.removeActivity(this);语句。此时,如果想要在某一个活动中直接能够退出程序,则可以注册事件执行ActivityCollector.finishAll();语句。

        此外,还可以在销毁所有活动之后杀掉当前进程,执行语句andoid.os.Process.killProcess(android.os.Process.myPid());

3.启动活动的最佳写法

        在目标活动中添加一个actionStart()方法

public static void actionStart(Context context,String data1,String data2){
    Intent intent = new Intent(context,SecondActivity.class);
    intent.putExtra("param1",data1);
    intent.putExtra("param2",data2);
    context.startActivity(intent);
}

        此时只需要一行代码就可以启动目标活动(SecondActivity),

SecondActivity.actionStart(FirstActivity.this,"data1","data2");

且不需要知道目标活动中需要的数据的键。

第三章 UI开发

一、常用控件

        控件的基本属性有android:id、android:layout_width、android:layout_height、android:text、android:gravity、android:visibility等。

        android:layout_width和android:layout_height属性用于设置控件的宽和高,可选值基本有match_parant和wrap_content,分别表示由父布局决定和由内容决定。

        android:graviry用于指定文本对齐方式,可选值有:top、bottom、left、right、center、center_vertical、center_horizontal等,可用“|”符号来同时指定多个值。

        android:visibility属性用于设置控件的可见性。可选值有visible(可见,默认值)、invisible(不可见,占据空间)、gone(不可见,不占空间)。

1.TextView

        最简单的android控件,用于显示文本。

        基本属性还有android:textSize、android:textColor等,用于设置字体大小于颜色。更多详情请参考官方文档。

        注:TextView类中的setText()方法的参数必须是String类型,否则程序无法正常运行。

2.Button

        用于和用户交互的重要控件。系统会自动将Button中的所有英文字母显示为大写形式,若不想要这种效果,可通过将android:textAllCaps属性值设置为false即可。更多详情可参考官方文档。

        Button作为可与用户交互的重要控件,可以响应用户的一系列操作事件,要实现这一功能,需要在活动类重写的onCreate()方法中为事件注册监听器。(以点击事件为例)

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            //实现逻辑功能
        }
    }    
);

        当Button较多时,可以使用实现接口的方式来进行注册:

@Override
protected void onCreate(Bundle savedInstanceState){
    ......
    button.setOnClickListener(this);
}

@Override
public void onClick(View v){
    switch (v.getId()){
        case R.id.button:
            //添加逻辑功能
            break;
        ......
        default:
            break;
    }
}

3.EditText

        用于和用户进行交互的另一个重要控件,可以输入和编辑内容,并对内容进行过处理。基本属性还有android:hint(指定输入框中的提示性文本)、android:maxLines(指定输入的最大行数,超出时文本向上滚动)等。

        EditText类获取输入框输入内容的方法是getText(),通常还需要调用toString()方法将其转换文字符串。

4.ImageView

        用于在界面上展示图片。图片资源通常放在"drawable"开头的目录下,一般放在drawable-xhdpi(没有就新建)目录下。

        导入图片的属性为android:src,此外,也可以通过事件动态地更改图片,只需要调用ImageView类的setImageResource()方法即可。

5.ProgressBar

        用于显示一个进度条。

        可根据需要使用ProgressBar类的setVisibility()方法来控制进度条的可见性,该方法可传入View.VISIBLE、View.INVISIBLE、View.GONE这3个值;也可通过它的getVisibility()方法获取该进度条当前的可见性。

        此外,还可以通过style属性更改进度条样式,如水平进度条。若是水平进度条,则可以通过android:max属性给进度条设置最大进度值,然后配合使用getProgress()方法和setProgress()方法动态地修改进度条的进度值。

int progress = progressBar.getProgress();
progress += 10;
progressBar.setProgress(progress);

6.AlertDialog

        弹出一个对话框。此控件无需在布局文件中进行设置,只需在活动类中设置。

AlertDialog.Builder dialog = new AlertDialog.Builder(context:MainActivity.this);
//创建Dialog实例
dialog.setTitle("this is a dialog");
dialog.setMessage("something important");
dialog.setCancelable(false);//是否可用“返回”键关闭对话框
dialog.setPositiveButton("ok",new DialogInterface.OnClickListener(){//设置确定按钮点击事件
    @Override
    public void onClick(DialogInterface dialog,int which){
    }
});
dialog.setNegativeButton("cancel",new DialogInterface.OnClickListener(){//设置取消按钮点击事件
    @Override
    public void onClick(DialogInterface dialog,int which){
    }
});
dialog.show();

7.ProgressDialog

        带进度条的对话框。用法与AlertDialog类似。

二、4种基本布局

1.线性布局(LinearLayout)

        控件线性排列。

        可由android:orientation属性指定排列方向,vertical(垂直)或horizental(水平,默认);垂直排列时,控件高度不能指定为match_parent,水平排列时,控件宽度不能指定为match_parent。

2.相对布局

3.帧布局

4.百分比布局

**第一次写博客,是我自己的学习笔记,还会更新,写下来方便自己后面查阅,

Logo

开源、云原生的融合云平台

更多推荐