2021-06-16

Android之基础

项目结构

  1. .gradle|.idea:

    1. Android studio自动生成的一些文件
  2. app

    1. 项目中的代码和资源存放位置

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wWQUB6YD-1623851607316)(C:\Users\xkadpz\AppData\Roaming\Typora\typora-user-images\image-20210515103752644.png)]

      1. build:编译时自动生成的文件

      2. libs:使用的第三方jar包,放在里面的jar包会自动添加路径到构建路径中

      3. AndroidTest:用来编写Android Test测试用例的,可以对项目进行自动化测试

      4. java:所有java代码

      5. res:项目中使用的所有图片、布局、字符串资源

        1. 图片:drawable
        2. 布局:layout
        3. 字符串:values
        4. 应用图标:mipmap

        加载res目录文件资源,例如res/value/string.xml.

        <resources>
         <string name="app_name">ActivityTest</string>
        </resources>
        
        1. 在代码中:R.string.app_name
        2. 在xml文件中:@string/app_name
      6. AndroidManifest.xml:整个Android项目配置文件。四大组件的注册,应用权限的声明等。

      7. test:用来编写Unit test测试用例的,对项目自动化测试的另外一种方式。

      8. .gitignore:将app模块内的指定的目录或文件排除在版本之外。

      9. build gradle:app模块的gradle构建脚本,指定很多项目构建相关的配置

        plugins {
        //    应用了一个插件,选值:'com.android.application':表示这是一个应用程序模块,可以直接运行
        //    com.android.application:表示这个一个库模块,只能依附于别的应用程序模块才能运行.
            id 'com.android.application'
        }
        //配置项目构建的各种属性
        android {
        //    用来指定项目的编译版本.30:表示Android11的SDK编译
            compileSdkVersion 30
        //    指定项目构建工具的版本.
            buildToolsVersion "30.0.3"
        
            defaultConfig {
        //        指定项目的包名.修改包名可以在这里修改
                applicationId "com.zhangtao.activitytest"
        //        项目最低兼容的Android版本
                minSdkVersion 16
        //        表示启动Android11的一些新特性.30代表11
                targetSdkVersion 30
        //        指定项目的版本号
                versionCode 1
        //        指定项目的版本名
                versionName "1.0"
        
                testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            }
        //指定生成安装文件的相关配置
            buildTypes {
        //        指定生成正式版安装文件的配置
                release {
        //            是否对项目的代码进行混淆
                    minifyEnabled false
        //            指定混淆时使用的规则文件.参1:SDK目录下,所用项目的通用的规则.参2:当前项目的根目录,编写当前项目特有的混淆规则
                    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
                }
            }
            compileOptions {
                sourceCompatibility JavaVersion.VERSION_1_8
                targetCompatibility JavaVersion.VERSION_1_8
            }
        }
        
        //指定当前项目的所有依赖关系
        dependencies {
        //三种依赖关系:本地依赖:本地的jar包或者目录添加依赖关系\库依赖:对项目的库模块添加依赖\远程依赖:对jcenter库上的开源项目添加依赖.
            implementation 'androidx.appcompat:appcompat:1.1.0'
            implementation 'com.google.android.material:material:1.1.0'
            testImplementation 'junit:junit:4.+'
            androidTestImplementation 'androidx.test.ext:junit:1.1.1'
            androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
        }
        
      10. proguard-reles.pro:项目diamagnetic的混淆规则

  3. gradle

    1. 包含了gradle wrapper的配置文件。可以自动下载gradle不需要提前下载,根据本地缓存。
  4. .gitignore

    1. 用来将指定的目录或者文件排除在版本之外
  5. build.gradle

    1. 全局的gradle的构建脚本

      // Top-level build file where you can add configuration options common to all sub-projects/modules.
      buildscript {
          repositories {
      //        jcenter代码托管平台.声明之后,可以引用里面的开源项目
              google()
              jcenter()
          }
          dependencies {
      //        声明gradle插件,用来构建Android项目
              classpath "com.android.tools.build:gradle:4.1.3"
      
              // NOTE: Do not place your application dependencies here; they belong
              // in the individual module build.gradle files
          }
      }
      
      
      allprojects {
          repositories {
              google()
              jcenter()
          }
      }
      
      task clean(type: Delete) {
          delete rootProject.buildDir
      }
      
  6. gradle.properties

    1. 全局的gradle配置文件,会影响项目中所有的gradle编译脚本
  7. gradlew|gradle.bat

    1. 在命令行执行gradle命令
  8. local.properties

    1. 用于指定本地的Android SDK路径
  9. settings.gradle

    1. 用于指定项目的所有引入的模块。

activity活动启动

//    继承父类的onCreate方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //加载布局文件,前后端分离
        setContentView(R.layout.hello_world_layout);
    }

Android之活动

package com.zhangtao.activitytest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class FirstActivity extends AppCompatActivity {

//    调用了父类的onCreate方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_layout);
        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(FirstActivity.this,"you onclick this",Toast.LENGTH_SHORT).show();
            }
        });
    }
//创建菜单项
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
//        通过getMenuInflater可以得到MenuInflater对象.调用它的inflate可以创建菜单.参1:指定通过哪一个资源文件来创建菜单,参2:指定菜单项将添加到哪一个对象中.
        getMenuInflater().inflate(R.menu.main,menu);
//        允许创建的展示出来
        return true;
    }
//响应菜单项点击的按钮
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case R.id.add_item:
                Toast.makeText(FirstActivity.this,"you onclick add",Toast.LENGTH_SHORT).show();
                break;
            case R.id.remove_item:
                Toast.makeText(FirstActivity.this,"you onclick remove",Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
        return true;
    }
}

方法:

  1. setContentView:加载布局文件
  2. findViewById:加载控件,如按钮
  3. setOnclickListener:监听按钮
  4. onCreateOptionsMenu方法。加载菜单按钮的时候一定也要重写。
  5. onOptionsItemSelected:菜单项按钮响应,里面写点击后的逻辑操作

活动的跳转:intent

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

类型:显示Intent和隐私Intent。

  1. Intent(Context packageContext,class<?>cls):参1:启动活动的上下文,参2:想要启动的目标活动。
  2. 通过startActivity方法启动。接受Intent参数。

显示Intent

//    调用了父类的onCreate方法
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_layout);
        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
                startActivity(intent);
            }
        });
    }

隐式Intent

不明确指出想要启动的活动,指定一系列的抽象的action和category。

每个Intent只能指定一个action,可以指定多个category

/*//                显示启动
                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
                startActivity(intent);*/
//                隐式启动/"com.example.activityTest.ACTION_START"在目标活动中需要存在..AndroidManifest.xml
                Intent intent = new Intent ("com.example.activityTest.ACTION_START");
//                目标活动中也要存在,AndroidManifest中
                intent.addCategory("com.ex.activity_MY_CATEGORY");
                startActivity(intent);
            }
拓展:

启动其他程序中的活动

<activity android:name=".ThirdActivity">
    <intent-filter tools:ignore="AppLinkUrlError">
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="http"/>
    </intent-filter>
</activity>
//启动内置的浏览器,在对应的活动AndroidManifest中<intent-filter>标签的<data>标签,指定和内置浏览器一致的,同样可以响应
public void onClick(View v) {
    //                内置action
    Intent intent = new Intent(Intent.ACTION_VIEW);
    //            通过Uri.setData将网页字符串解析称一个Uri对象,再通过setData将Uri对象传递进去.setData用于指定当前Intent正在操作的数据..还需要在AndroidManifest文件中配置<data>标签
    //                更精确的指定当前活动能够响应什么类型的数据,需要和Data一直
    intent.setData(Uri.parse("http://www.baidu.com"));
    startActivity(intent);
}

向下一个活动传递数据

源活动:activity1

//                向下一个活动传递数据
                String data = "hi,second,i'm first";
                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
//                通过putExtra传递数据.参1:为健,用于后面 的活动从Intent中取值,参2:是想要传递的数据.
                intent.putExtra("extra_data",data);
                startActivity(intent);

目的活动:activity2

//        打印出从FirstActivity传递过来的值
        Intent intent = getIntent();//用于获取启动SecondActivity的Intent
        String data = intent.getStringExtra("extra_data");//通过getStringExtra传入响应的键值,可以得到对应的值.
        Log.d(TAG, "onCreate: data:"+data);

返回数据给上一个活动

通过startActivityForResult方法。参1:Intent,参2:请求码,用于之后回调判断数据的来源。

//                接受从下一个活动传递上来的数据.
                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
//                请求吗唯一即可
                startActivityForResult(intent,1);


//重写onActivityResult方法;
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (1){
            case 1:
                if (requestCode == RESULT_OK){
                    Log.d(TAG, "onActivityResult: 11111");
                    String returnedData = data.getStringExtra("data_return");
                    Log.d(TAG, "onActivityResult: return"+returnedData);
                }
                break;
            default:
                Log.d(TAG, "onActivityResult: ssss");
                break;
        }
    }
            public void onClick(View v) {
//                向上一个活动传递数据
            Intent intent = new Intent();

            intent.putExtra("data_return","hi,i'm activity2");
                //            参1:用于向上一个活动放回处理结果.参2:把带有数据的intent携带过去.
            setResult(RESULT_OK,intent);

//            在执行finish之前,会回调上一个活动的onActivityforResult方法
            finish();
            }

活动回收

在活动回收之前,保存活动状态,保存里面的信息

onSaveInstanceState:重写这个方法,可以保证活动被回收之前,一定会被调用。这个方法会携带一个Bundle类型的参数,通过putString方法保存字符串

//  保证活动被回收之前,一定会被调用.携带一个Bundle类型的参数,提供了一些方法用于保存数据.
    @Override
    public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        String tempData = "something you just typed";
//        通过putString方法保存字符串.参1:健,用于后面从Bundle取值,参2:实际要保存的数据
        outState.putString("data_key",tempData);
    }

在onCreate中取出这个数据

if (savedInstanceState != null){
    String tempData = savedInstanceState.getString("data_key");
    Log.d(TAG, "onCreate: tempData"+tempData);
}

如何快速知晓当前活动

新建一个BaseActivity类,让其他活动继承这个类

public class BaseActivity extends AppCompatActivity {
    private static final String TAG = "BaseActivity";
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, getClass().getSimpleName());
    }
}

活动的生命周期

onCreate:活动第一次被创建的时候调用,完成活动的初始化动作。如布局加载,绑定事件

onStart:活动由不可见变为可见的时候调用。

onResume:活动准备和用于进行交互的时候调用,此时活动处于返回栈的栈顶,并且处于运行时状态。

onPause:系统准备去启动或者恢复另外一个活动的时候调用。在这个方法中将一些消耗CPU的资源释放掉,以及保存一些关键数据。

onStop:活动完全不可见的时候调用,与onPause对比,当启动的新活动是一个对话框式的活动,onPause会被启动,onStop不会启动。

onDestory:在活动被销毁之前调用,之后活动的状态变成销毁状态

onRestart:活动由停止状态变为运行状态之前调用,即活动被重新启动。

上一篇:分享到第三方APP,比如微信、QQ等


下一篇:Activity的启动流程-第二篇