• 第一章 开启安卓之路


    • 前言

      ​ 本文是基于《第一行代码》整理成的笔记,mark下自己的学习路程。

      ​ 本章将通过实验着重介绍ACtivity。


    • 项目结构

      ​ 首先我们创建一个安卓项目,来认识一下项目结构;

      ![]({{ site.url }}/assets/blog_images/2018-06-12_091623.jpg)

    assets		//主要可以存放一些随程序打包的文件,不需要过多关注
    bin			//里面会有程序的apk,拷贝到手机就可以安装了
    gen			//该目录自动生成,例如 R.java ,不要轻易修改
    libs		//第三方jar包
    src			//源代码
    res	//重点
    	{
            drawable	//图片
            layout		//布局文件xml
            values		//字符串
        AndroidManifest.xml //整个项目的配置文件,在程序定义的四大组件都要在此注册
        project.properties	//指定程序所使用的SDK版本
    	}
    
    • 四大组件之首——Activity

      Activity 就是我们所看到的界面,新建一个类,继承Activity,重写onCreate方法即可创建Activity;

      每新建一个活动,都需要在 AndroidManifest.xml 注册;

      public class MainActivity extends Activity {
      	@Override
      	protected void onCreate(Bundle savedInstanceState) {
      		super.onCreate(savedInstanceState);
      		setContentView(R.layout.activity_main);	//加载布局文件
      	}
      }
      
    • 活动的生命周期

      ![]({{ site.url }}/assets/blog_images/2018-06-12_095142.jpg)

      需要注意的是,在上图中,发生 onPause() 和 onStop() 这一行为是有所区别的;

      当当前的Activity部分被遮挡住时,只会调用 onPause();只有完全遮挡才会调用 onStop() ;

      • 实验理解

        新建MainActivity和SecondActivity,为它们的设置一个按钮用来彼此跳转,查看它们的状态;

      // MainActivity
      public class MainActivity extends BaseActivity {
      	static String TAG="MainActivity";
      	@Override
      	protected void onCreate(Bundle savedInstanceState) {
      		super.onCreate(savedInstanceState);
      		Log.d(TAG, "onCreate");
      		setContentView(R.layout.activity_main);
      		Button btn1 = (Button) findViewById(R.id.btn1);
      		btn1.setOnClickListener(new OnClickListener() {
      			
      			@Override
      			public void onClick(View v) {
      				SecondActivity.actionStart(MainActivity.this);
      			}
      		});
      	}
      	
      	public static void actionStart(Context context) {
      		Intent intent = new Intent(context,MainActivity.class);
      		context.startActivity(intent);
      	}
      
      	@Override
      	protected void onDestroy() {
      		super.onDestroy();
      		Log.d(TAG, "onDestroy");
      	}
      
      	@Override
      	protected void onPause() {
      		super.onPause();
      		Log.d(TAG, "onPause");
      	}
      
      	@Override
      	protected void onRestart() {
      		super.onRestart();
      		Log.d(TAG, "onRestart");
      	}
      
      	@Override
      	protected void onResume() {
      		super.onResume();
      		Log.d(TAG, "onResume");
      	}
      
      	@Override
      	protected void onStart() {
      		super.onStart();
      		Log.d(TAG, "onStart");
      	}
      
      	@Override
      	protected void onStop() {
      		super.onStop();
      		Log.d(TAG, "onStop");
      	}
      }
      
      
      //SecondActivity
      public class SecondActivity extends BaseActivity {
      	static String TAG="SecondActivity";
      	@Override
      	protected void onCreate(Bundle savedInstanceState) {
      		super.onCreate(savedInstanceState);
      		Log.d(TAG, "onCreate");
      		setContentView(R.layout.activity_second);
      		Button btn2 = (Button) findViewById(R.id.btn2);
      		btn2.setOnClickListener(new OnClickListener() {
      			
      			@Override
      			public void onClick(View v) {
      				MainActivity.actionStart(SecondActivity.this);
      			}
      		});
      	}
      	public static void actionStart(Context context) {
      		Intent intent = new Intent(context,SecondActivity.class);
      		context.startActivity(intent);
      	}
      	@Override
      	protected void onDestroy() {
      		super.onDestroy();
      		Log.d(TAG, "onDestroy");
      	}
      
      	@Override
      	protected void onPause() {
      		super.onPause();
      		Log.d(TAG, "onPause");
      	}
      
      	@Override
      	protected void onRestart() {
      		super.onRestart();
      		Log.d(TAG, "onRestart");
      	}
      
      	@Override
      	protected void onResume() {
      		super.onResume();
      		Log.d(TAG, "onResume");
      	}
      
      	@Override
      	protected void onStart() {
      		super.onStart();
      		Log.d(TAG, "onStart");
      	}
      
      	@Override
      	protected void onStop() {
      		super.onStop();
      		Log.d(TAG, "onStop");
      	}
      }
      
      

      启动项目,默认首页是MainActivity;

      ![]({{ site.url }}/assets/blog_images/2018-06-12_133155.jpg)

        我们可以看到,实例化Activity的步骤:onCreate -> onStart -> onResume ;
        
        让我们点击下按钮 “跳转到SecondActivity”;
        
        	 ![]({{ site.url }}/assets/blog_images/2018-06-12_135426.jpg)
      

    此时SecondActivity完全将MainActivity遮蔽,所以,MainActivity会调用onStop方法;

    再点下按钮 “跳转到MainActivity”;

    ![]({{ site.url }}/assets/blog_images/2018-06-12_140323.jpg)

    我们看到,MainActivity调用onRestart ,而SecondActivity由于已经完成任务,所以调用销毁方法;

    • 活动的启动模式

      <!-- 在 AndroidManifest.xml中指定模式即可改变 -->
      <activity
          android:launchMode="singleTop"	<!-- 有四个模式可选 -->
          android:name="com.example.hello.MainActivity"
          android:label="@string/app_name" >
          <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
      </activity>
      
      • standard

        顾名思义,就是标准的意思,也就是活动的默认模式;在standard模式下,每启动一个新的活动,它就会入栈,并且处于栈顶位置;对于该模式的活动系统不会在乎该活动是否已在栈中存在,就算它处于栈顶也一样,每次启动都会创建一个新的实例。

      • singleTop

        在某些情况下,standard模式并不合理;例如,活动明明处于栈顶,为什么还要新建实例?

        所以聪明的设计者开发了singleTop模式,意思就是,当即将新建的Activity处于栈顶时,系统将直接调用,而不会新建;

      • singleTask

        使用singleTop模式可以很好地解决重复创建栈顶活动的问题,如果活动没有处于栈顶,singleTop就无法满足需求了,它还是会新建实例,这时候就要 singleTask 登场了;它的意思就是,只要栈中存在即将新建的活动,系统都不会生成,而是重新将其调回栈顶位置;

      • singleInstance

        不同于以上三种模式,singleInstance 模式下的活动会启用一个新的返回栈来管理这个活动;

        我们来构建下场景,新建三个活动 A、B、C;其中 B 采用 singleInstance ,其他两个采用 singleTask ,我们分别为每个活动设置一个按钮,用来页面的跳转,按下 A 来到 B,按下 B 来到 C ,如果在 C 我们按下返回键会怎么样?没错,意外的是,它直接跳转到 A ,这又该如何理解?

        其实原理很简单,我们看到下图,其实A和B是处于同一个栈,所以结束C自然会跳转到A,当结束A时,此时左边栈就空了,自然会返回B;

        ![]({{ site.url }}/assets/blog_images/2018-06-12_105141.jpg)

    • 活动实践

      下面将介绍几种活动运用的小技巧;

      • 知晓当前处于哪个活动

        对于我们自己写的项目,我们当然能快速判断这是哪个活动,但如果是别人写的项目就很麻烦了;

        我们新建一个名为 BaseActivity 继承自 Activity ,然后重写 onCreate() 方法,如下:

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

        最后只需要将其他类改成继承自 BaseActivity 即可。

      • 随时随地退出程序

        思路其实就是,建立一个专门用来管理所有活动的类——ManagerActivity;

        //代码
        public class ManagerActivity extends Activity {
        	public static List<Activity> activities = 
                						new ArrayList<Activity>();
        	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.isFinishing()) {
        				activity.finish();
        			}
        		}
        	}
        }
        
        

        我们还可以将在BaseActivity中调用ManagerActivity,这样我们只需调用 finishAll() 就可以随时随地退出程序;

        public class BaseActivity extends Activity {
        	@Override
        	protected void onCreate(Bundle savedInstanceState) {
        		super.onCreate(savedInstanceState);
        		Log.d("LocationActivity", getClass().getSimpleName());
        		ManagerActivity.addActivity(this);
        	}
        
        	@Override
        	protected void onDestroy() {
        		super.onDestroy();
        		ManagerActivity.removeActivity(this);
        	}
        }
        
      • 启动活动的最佳方法

        如果我们要从 FirstActivity 传递两个参数到 SecondActivity ,我们可以这么写:

        Intent intent = new Intent(FirstActivity.this,
                                   		SecondActivity.class);
        intent.putExtra("param1", "data1");
        intent.putExtra("param2", "data2");
        startActivity(intent);
        

        这当然可以,但如果 SecondActivity 不是你开发的呢?而你又有需要调用启动 SecondActivity ,又该怎么解决?其实我们可以为 SecondActivity 写一个启动方法,这样其他人就一目了然了。

        public class SecondActivity extends BaseActivity {
            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);
            }
        }
        

        这样,别人只需要调用方法actionStart,填上参数就可以轻松启动。

  • 相关阅读:
    Unity错误-(Android build error) Can not sign application Unable to sign application; please provide passwords!
    C#WCF中传输List对象
    抓包工具Omnipeek,Wireshark
    Ubuntu18+.netcore+Nginx+Supervisor部署ASP.NET项目
    3D成像技术
    3D显示技术
    学习模电与数电
    【Java123】解决PKIX path building failed / unable to find valid certification path to requested target
    【Python123】Introduction
    【WebConsole123】练习案例之浏览器访问服务器shell
  • 原文地址:https://www.cnblogs.com/jackpon/p/9337185.html
Copyright © 2020-2023  润新知