Android入门
1,
每个 Intent 中只能指定一个 action,但却能指定多个 category。
2,
总结一下,在编写 Android 程序的时候,尽量将控件或布局的大小指定成 match_parent
或 wrap_content,如果必须要指定一个固定值,则使用 dp 来作为单位,指定文字大小的时候
使用 sp 作为单位。
3,
可以将Activity理解为JSP页面,PHP页面,HTML标签可以理解为View属性,Activity的本质是承载界面的框架。Activity这个类有1万多行代码。
4,
生命周期运行图(来自于Android社区,androidcommunitydocs.com)
当Activity的onResume()方法执行完成之后,我们就可以看到这个界面了。
示例代码:
public class MainActivity extends AppCompatActivity { public static final String TAG = "nate"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e(TAG, "onCreate: MainActivity"); setContentView(R.layout.activity_main); } @Override protected void onStart() { super.onStart(); Log.e(TAG, "onStart: MainActivity"); } @Override protected void onRestart() { super.onRestart(); Log.e(TAG, "onRestart: MainActivity"); } @Override protected void onResume() { super.onResume(); Log.e(TAG, "onResume: MainActivity"); } @Override protected void onPause() { super.onPause(); Log.e(TAG, "onPause: MainActivity"); } @Override protected void onStop() { super.onStop(); Log.e(TAG, "onStop: MainActivity"); } @Override protected void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy: MainActivity"); } }
在手机界面点击这个app(手机设置常亮),启动MainActivity,打印日志如下:
点击返回键(或者切换其他程序),输出日志如下:
onStop()相当于把app挂起,处于【隐藏】状态。
在手机待运行的程序区里点击这个app,打印的输出日志如下:
5,
总结:
显示状态:onCreate,onStart,onResume
半看见状态:onPause
看不见状态:onStop
销毁状态:onDestory
6,
Activity生命周期交互设计思想
为什么要先暂停当前显示的Activity ?
为什么要先执行要打开的Activity的onCreate, onStart, onResume方法呢?
在打开新Activity的时候,为什么不先执行当前Activity的onPause, onStop方法呢?
7,
crush:因为程序或者各种原因而导致的程序意外退出,俗称“闪退”
8,
手机在横竖屏切换的时候,会销毁当前这个Activity,并重新创建。
9,
//当前Activity销毁的时候,保存一些状态信息,在横竖屏调换的时候去存储一些信息 @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); }
10,
完整示例代码:
package com.example.activity_01; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.media.MediaPlayer; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; //实现单击事件 public class MainActivity extends AppCompatActivity implements View.OnClickListener { public static final String TAG = "nate"; private Button button; private TextView textView; private MediaPlayer mediaPlayer; /*当前Activity销毁的时候,保存一些状态信息,在横竖屏调换的时候去存储一些信息 这些信息会存储到系统当中*/ @Override protected void onSaveInstanceState(@NonNull Bundle outState) { Log.e(TAG, "onSaveInstanceState: MainActivity"); super.onSaveInstanceState(outState); outState.putString("name", "黄朝阳"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e(TAG, "onCreate: MainActivity"); setContentView(R.layout.activity_main); button = findViewById(R.id.button2); textView = (TextView) findViewById(R.id.textView); button.setOnClickListener(this); if (savedInstanceState != null) { textView.setText(savedInstanceState.getString("name")); } } @Override protected void onStart() { super.onStart(); Log.e(TAG, "onStart: MainActivity"); } @Override protected void onRestart() { super.onRestart(); Log.e(TAG, "onRestart: MainActivity"); } @Override protected void onResume() { super.onResume(); Log.e(TAG, "onResume: MainActivity"); } @Override protected void onPause() { super.onPause(); Log.e(TAG, "onPause: MainActivity"); } @Override protected void onStop() { super.onStop(); Log.e(TAG, "onStop: MainActivity"); } @Override protected void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy: MainActivity"); } @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); } }
11,
生命周期的运用,嵌入音频进行理解
package com.example.activity_01; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.media.MediaPlayer; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; //实现单击事件 /* * 1.在初始化MediaPlayer时,通过create方法设置数据源。 * 则不能写MediaPlayer.prepare()方法,这时,会报错。 2.如果是使用MediaPlayer构造函数初始化MediaPlayer,然后通过setDataSource方法设置数据源时, * 就需要在start()之前,使用MediaPlayer.prepare()方法,对数据源进行一次编译。能够避免出现(-38,0)这种错误。 * */ public class MainActivity extends AppCompatActivity implements View.OnClickListener { public static final String TAG = "nate"; private Button button; private TextView textView; //播放视频对象 private MediaPlayer mediaPlayer; //记录多媒体播放的位置 private int postion; /*当前Activity销毁的时候,保存一些状态信息,在横竖屏调换的时候去存储一些信息 这些信息会存储到系统当中*/ @Override protected void onSaveInstanceState(@NonNull Bundle outState) { Log.e(TAG, "onSaveInstanceState: MainActivity"); super.onSaveInstanceState(outState); outState.putString("name", "黄朝阳"); //停止媒体播放 // mediaPlayer.stop(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e(TAG, "onCreate: MainActivity"); setContentView(R.layout.activity_main); button = findViewById(R.id.button2); textView = (TextView) findViewById(R.id.textView); button.setOnClickListener(this); if (savedInstanceState != null) { textView.setText(savedInstanceState.getString("name")); } mediaPlayer = MediaPlayer.create(this, R.raw.qq); mediaPlayer.start(); } @Override protected void onStart() { super.onStart(); Log.e(TAG, "onStart: MainActivity"); } @Override protected void onRestart() { super.onRestart(); Log.e(TAG, "onRestart: MainActivity"); } @Override protected void onResume() { super.onResume(); Log.e(TAG, "onResume: MainActivity"); if (postion != 0) { //跳转到当前播放状态 mediaPlayer.seekTo(postion); //继续播放 mediaPlayer.start(); } } @Override protected void onPause() { super.onPause(); Log.e(TAG, "onPause: MainActivity"); //判断当前媒体是否在播放 if (mediaPlayer.isPlaying()) { //暂停播放 mediaPlayer.pause(); //记录媒体当前的播放位置 postion = mediaPlayer.getCurrentPosition(); } } @Override protected void onStop() { super.onStop(); Log.e(TAG, "onStop: MainActivity"); } @Override protected void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy: MainActivity"); //销毁媒体内存 mediaPlayer.release(); } @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); } }
12,
完整代码:
package com.example.activity_01; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.media.MediaPlayer; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; //实现单击事件 /* * 1.在初始化MediaPlayer时,通过create方法设置数据源。 * 则不能写MediaPlayer.prepare()方法,这时,会报错。 2.如果是使用MediaPlayer构造函数初始化MediaPlayer,然后通过setDataSource方法设置数据源时, * 就需要在start()之前,使用MediaPlayer.prepare()方法,对数据源进行一次编译。能够避免出现(-38,0)这种错误。 * */ public class MainActivity extends AppCompatActivity implements View.OnClickListener { public static final String TAG = "nate"; private Button button; private TextView textView; //播放视频对象 private MediaPlayer mediaPlayer; //记录多媒体播放的位置 private int postion; /*当前Activity销毁的时候,保存一些状态信息,在横竖屏调换的时候去存储一些信息 这些信息会存储到系统当中*/ @Override protected void onSaveInstanceState(@NonNull Bundle outState) { Log.e(TAG, "onSaveInstanceState: MainActivity"); super.onSaveInstanceState(outState); outState.putString("name", "黄朝阳"); //停止媒体播放 // mediaPlayer.stop(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.e(TAG, "onCreate: MainActivity"); setContentView(R.layout.activity_main); button = findViewById(R.id.button2); textView = (TextView) findViewById(R.id.textView); button.setOnClickListener(this); if (savedInstanceState != null) { textView.setText(savedInstanceState.getString("name")); } mediaPlayer = MediaPlayer.create(this, R.raw.qq); mediaPlayer.start(); } @Override protected void onStart() { super.onStart(); Log.e(TAG, "onStart: MainActivity"); } @Override protected void onRestart() { super.onRestart(); Log.e(TAG, "onRestart: MainActivity"); } @Override protected void onResume() { super.onResume(); Log.e(TAG, "onResume: MainActivity"); if (postion != 0) { //跳转到当前播放状态 mediaPlayer.seekTo(postion); //继续播放 mediaPlayer.start(); } } @Override protected void onPause() { super.onPause(); Log.e(TAG, "onPause: MainActivity"); //判断当前媒体是否在播放 if (mediaPlayer.isPlaying()) { //暂停播放 mediaPlayer.pause(); //记录媒体当前的播放位置 postion = mediaPlayer.getCurrentPosition(); } } @Override protected void onStop() { super.onStop(); Log.e(TAG, "onStop: MainActivity"); } /*onDestory方法是非常关键的方法,使用Holder, ViewHolder需要在这里进行释放资源 ,如果不在这里进行释放资源,app就会越用越慢,这些问题处于【内存泄露】, 导致Activity无法释放*/ @Override protected void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy: MainActivity"); //销毁媒体内存,先判空 if (mediaPlayer != null) { mediaPlayer.release(); mediaPlayer = null; } } @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); } }
13,
Activity启动的方式:直接启动和匿名启动
如果要启动【微信】的Activity界面时,微信不会直接提供Activty,就需要用匿名方式启动,
14,
隐式启动Activity
@Override public void onClick(View v) { //通过匿名启动第5个Activity Intent intent = new Intent(); intent.setAction("www.imooc.com"); startActivity(intent); }
Category属性用于指定当前动作(Action)被执行的环境
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.activity_01"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".ThreeActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SecondActivity" /> <activity android:name=".FourActivity" /> <activity android:name=".FiveActivity" > <intent-filter> <action android:name="www.imooc.com"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> </application> </manifest>
15,
启动系统常见的Activity
16,查阅Android API的android.content.Intent类,可以查到对应的参数和对应的功能
17,