一、安卓应用和开发环境简介
1.安卓的系统特性与平台架构
- 系统特性
- 应用程序框架支持组件的重用和替换
- Dalvik虚拟机:专门未移动设备优化
- SQLite结构化的数据存储
- 采用软件叠层方式构建
- 平台架构图
- 应用程序层(Application)
- 应用程序框架层(Application Framework)
- 函数库(libraries)
- 安卓运行时(android runtime):核心库集+Dalvik虚拟机
- linux内核
2.环境搭建
- JDK安装与配置
- 下载JDK
- 安装JDK
- 环境变量配置(JAVA_HOME,CLASSPATH)
- SDK下载
- AS下载安装
3.相关术语
- Dalvik:安卓特有的虚拟机,和jvm不同,其适合在移动终端使用
- AVD(android virtual machine):安卓虚拟设备,模拟器
- ADT(android development tools):安卓开发工具
- SDK(software development kit):软件开发共举杯
- DDMS(dalvik debug monitor service):安卓调试工具
- adb:安卓调试桥,在sdk的platform-tools目录下,功能很多,命令行必备
- DX工具:将.class转换成.dex文件
- AAPT:(android asset packing tool),安卓资源打包工具
- R.java文件:由aapt工具根据App中的资源文件自动生成,可以理解为资源字典
- AndroidManifest.xml:app包名 + 组件声明 + 程序兼容的最低版本 + 所需权限等程序的配置文件
二、探究活动(activity)
1、基本组件显示
-
在.xml文件中添加布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button 1" /> </LinearLayout>
-
在主活动中加载布局setContetView(R.layout.first_layout)
public class FirstActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first_layout); } }
-
在配置文件中注册,标定主活动。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.activitytest"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".FirstActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
2、使用Toast(提醒)
点击按钮弹出一个Toast,在onCreat()方法中添加功能
rotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(FirstActivity.this, "You clicked Button 1",
Toast.LENGTH_SHORT).show();
}
});
}
步骤:首先是要通过findViewById()方法获取到布局文件中定义的元素,然后由于是View对象,需要向下转型为Button对象,得到实例后,调用setOnClickListener()方法为按钮注册一个监听器,在重写onClick方法中写功能。Toast调用静态方法manketext,传入三个参数,分别是Context,文本显示内容,以及显示时间,最后调用show。
3、使用Menu
步骤:
-
首先要使用菜单,就需要先添加布局,这里可以不用自己设计布局,而是直接建立菜单文件。在res目录下新建一个menu文件夹,右击res目录→New→Directory,输入文件夹名menu,点击OK。接着在这个文件夹下再新建一个名叫main的菜单文件,右击menu文件夹→New→Menu resource file
-
在文件里面添加菜单项。
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/add_item" android:title="Add"/> <item android:id="@+id/remove_item" android:title="Remove"/> </menu>
-
添加好了布局文件,就可以编写逻辑啦。首先在活动中重写 onCreateOptionsMenu()方法。调用getMenuInflater() 方法能够得到MenuInflater 对象,再调用它的inflate() 方法就可以给当前活动创建菜单了。inflate() 方法接收两个参数,第一个参数用于指定我们通过哪一个资源文件来创建菜单,这里当然传入R.menu.main 。第二个参数用于指定我们的菜单项将添加到哪一个Menu 对象当中,这里直接使用onCreateOptionsMenu() 方法中传入的menu 参数。然后给这个方法返回true ,表示允许创建的菜单显示出来。
public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; }
现在只是得到显示出来,还没有加入功能,同样,重写onOptionsItemSelected()方法来调用id,选择对应的菜单,加入Toast。
public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.add_item: Toast.makeText(this, "You clicked Add", Toast.LENGTH_SHORT).show(); break; case R.id.remove_item: Toast.makeText(this, "You clicked Remove", Toast.LENGTH_SHORT).show(); break; default: } return true; }
4、使用Intent在活动之间穿梭
目前,只有一个活动,很简单,下面来两个活动试试。Intent就是各组件之间进行交互的一种方式,一般用于启动活动、服务以及广播等场景。分为显示和隐式。
4.1 使用显示Intent
-
首先要创建第二个活动,右击com.example.activitytest包→New→Activity→Empty Activity,会弹出一个创建活动的对话框,我们这次将活动命名为SecondActivity,并勾选Generate Layout File,给布局文件起名为second_layout,但不要勾选Launcher Activity选项
-
编辑second_layout.xml文件,添加一个按钮。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button 2" /> </LinearLayout>
-
编写好布局文件,就应该编写java文件,但是现在不需要有什么动作,所以去注册文件里配置主活动,已经自动配置好了,现在修改主活动中的按钮点击事件,将之前的Toast换成点击跳转。创建一个Intent对象,第一个参数为本活动,第二个参数为要跳转到的活动,最后调用startActivity,传入intent.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 =(Button) findViewById(R.id.button_1); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Toast.makeText(MainActivity.this,"点击了我",Toast.LENGTH_SHORT).show(); Intent intent = new Intent(MainActivity.this, Main2Activity.class); startActivity(intent); } }); }
4.2 使用隐式Intent
-
和显示相比,不具体指定由哪里跳到哪里,而是在配置文件中,先定义好一个字符串,再在intent里面引用这个固定的属性即可。在配置文件中
<activity android:name=".SecondActivity" > <intent-filter> <action android:name="com.example.activitytest.ACTION_START" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
-
在主活动中
button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("com.example.activitytest.ACTION_START"); startActivity(intent); } });
-
使用隐式intent,不仅可以启动自己程序内的活动,还可以启动其他程序的活动,因此多个应用程序之间可以功能共享切换,比如打开百度网页。
button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.baidu.com")); startActivity(intent); } });
先指定了intent的action是Intent.ACTION_VIEW,这是内置动作,其常量值为android.intent.action.VIEW ,相当于在配置文件中name属性定义为这个。通过Uri.prase()方法将一个网址字符串解析成一个Uri对象,再调用intent的setData()方法将对象传递出去。
4.3、向下一个活动传递数据
- 首先假设要传的数据定义为一个字符串,通过putExtra()方法来传递,两个参数,一个是键,一个是值
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data = "Hello SecondActivity";
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("extra_data", data);
startActivity(intent);
}
});
- 在secondactivity中通过getIntent来获取intent,然后用getstringectra()方法传递数据,如果传递的是整型数
据,则使用getIntExtra() 方法;如果传递的是布尔型数据,则使用getBooleanExtra()方法,以此类推
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Log.d("SecondActivity", data);
}
}
4.4、返回数据给上一个活动
在第一个活动中修改按钮点击事件,startActivityForResult() 方法接收两个参数,第一个参数还是Intent,第二个参数是请求码,用于在之后的回调中判断数据的来源
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent, 1);
}
});
使用了startActivityForResult() 方法来启动SecondActivity,请求码只要是一个唯一值就可以了,这里传入了1。接下来我们在SecondActivity中给按钮注册点击事件,并在点击事件中添加返回数据的逻辑
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("data_return", "Hello FirstActivity");
setResult(RESULT_OK, intent);
finish();
}
});
}
}
调用了setResult() 方法。这个方法非常重要,是专门用于向上一个活动返回数据的。setResult() 方法接收两个参数,第一个参数用于向上一个活动返回处理结果,一般只使用RESULT_OK 或RESULT_CANCELED 这两个值,第二个参数则把带有数据的Intent传递回去,然后调用了finish() 方法来销毁当前活动。SecondActivity被销毁之后会回调上一个活动的onActivityResult() 方法,因此我们需要在FirstActivity中重写这个方法来得到返回的数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
String returnedData = data.getStringExtra("data_return");
Log.d("FirstActivity", returnedData);
}
break;
default:
}
}
onActivityResult() 方法带有三个参数,第一个参数requestCode ,即我们在启动活动时传入的请求码。第二个参数resultCode ,即我们在返回数据时传入的处理结果。第三个参数data ,即携带着返回数据的Intent
5、活动的生命周期
- onCreate():第一次呗创建的时候调用
- onStart():由不可见变为可见的时候调用
- onResume():在活动准备好和用户进行交互的时候调用,此时一定处于栈顶,处于运行状态
- onPause():在系统准备去启动或者恢复的时候调用
- onStop():在完全不可见的时候调用
- onDetrory():在被销毁之前调用,之后活动变为销毁状态
- onRestart():由停止状态变为运行状态时调用
6、活动的启动模式
- standard
-
singleTop
-
singleTask
-
singleInstance