Android入门
目录
一、安卓项目结构
AndroidMaifest.xml: 声明应用程序模块名、图标、包名、组件、授权
- 每个Activity需要在该文件声明,若为主活动组件还需要声明<intent-filter>意图过滤器,且过滤器中需要包含MAIN动作(action标签)和LAUNCHER类别(category标签)
- 例1: AndroidMaifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.abing.login"> <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=".ui.login.LoginActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>- 例2: AndroidMaifest.xml-activity标签
<activity android:name="com.example.DemoActivity" android:clearTaskOnLaunch="true" <!-- 配 置 变 化 触 发 事 件 --> android:configChanges="orientation|keyboardHidden" <!-- Activity 的标题 --> android:label="@string/title_scan" android:parentActivityName=".activity.ResearchActivity" <!-- 启 动 时 屏 幕 的 方 向 --> android:screenOrientation="sensorPortrait" android:stateNotNeeded="true" android:theme="@style/AppTheme.NoActionBar" <!-- 禁 止 软 键 盘 --> android:windowSoftInputMode="stateAlwaysHidden"> </activity>
二、监听器,适配器
- 设置点击监听器的两种方式: 1.xml 2.setOnClickListener
- 例setOnClickListener
findViewById(R.id.btnId).setOnClickListener(onClickListener); private View.OnClickListener onClickListener=new View.OnClickListener() { @Override public void onClick(View v){ Toast.makeText(MainActivity.this,"Button 点击事件",Toast.LENGTH_LONG).show(); } }; - 设置ListView数据源:1.xml-androd:entries="@array/cities" 2.Adapter
- ArraryAdapter
//数组数据源 String[] data = {"","",""}; //获取listView对象 ListView listView = (ListView)findViewById(R.id.list_view); //创建ArrayAdapter ArrayAdapter<String> adapter = new ArraryAdapter<String>( MainActivity.this,android.R.layout.simple_list_item_1,data ) //组件绑定适配器 listView.setAdapter(adapter); //定义列表项点击事件监听器,覆盖他的点击事件回调方法 listView.setOnItemClickListener(new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> parent,View view ,int position,long id){ Toast.makeText(this,"您选择的是"+data[position],Toast.LENGTH_LONG).show(); } })- SimpleAdapter
String[] mTitle = {"姓名","性别","年龄"}; String[] mStr = {"张三","男","20"}; ArrayList<Map<String,Object>> mData= new ArrayList<Map<String,Object>>(); int lengh = mTitle.length; for(int i =0; i < lengh; i++) { Map<String,Object> item = new HashMap<String,Object>(); item.put("image", R.drawable.jay); item.put("title", mTitle[i]); item.put("text", mStr[i]); mData.add(item); } //获得 ListView 对象 ListView listView=(ListView)findViewById(R.id.list_view); //创建 SimpleAdapter 对象 SimpleAdapter adapter = new SimpleAdapter(this,mData,R.layout.simple_item, new String[]{"image","title","text"}, new int[]{R.id.image,R.id.title,R.id.text}); //绑定 ArrayAdapter listView.setAdapter(adapter); //注册点击事件监听器 listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position,long id) { Toast.makeText(this,"您选择标题: " + mTitle [position]+ "内容是:"+mStr [position],Toast.LENGTH_LONG).show(); } });
三、启动Activity
- 显式启动
//创建一个 Intent 对象,指定要启动的Activity 组件类。然后调用 startActivity()方法
Intent intent = new Intent(MainActivity.this, MyActivity.class);
startActivity(intent);
- 隐式启动
//指定一个(拨号)动作,让系统选择能执行该动作的Activity,然后将请求转交给这个(拨号)Activity处理
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(“tel:571-989898”));
startActivity(intent);
四、获取Activity返回值
- 通常把调用 startActivity()方法的 Activity 称为父 Activity,被启动的 Activity 称为子 Activity。
启动子 Activity
- 第一个参数是 Intent 对象。第二个参数是请求码。它用于唯一标识一个子 Activity,父Activity 在获取子 Activity 的返回值时用到。
int SUBACTIVITY1=1; Intent intent=new Intent(this,ChildActivity.class); startActivityForResult(intent,SUBACTIVITY1);或者
Int SUBACTIVITY2=2; Intent intent=new Intent(Intent.ACTION_CALL,Uri.parse(“tel:10086”)); startActivityForResult(intent,SUBACTIVITY2);设置子 Activity 的返回值
- 在子 Activity 调用 finish()方法关闭自己之前,需要调用 setResult()方 法将数据信息返回给父 Activity。
Intent intent=new Intent(); intent.putExtra("name", "Petter"); // intent.putExtras(Bundle bundle) //第一个参数是子 Activity 的返回状态码,通常为 Activity.RESULT_OK 或 Activity.RESULT_CANCELED, //第二个参数是 Intent 对象,该 Intent 对象就是子Activity 返回数据给父 Activity 的重要载体。 setResult(RESULT_OK, intent); finish();父 Activity 获取返回值
- 当子 Activity 关闭时,其父 Activity 的 onActivityResult()回调方法会 被调用,并将子 Activity 的返回值以参数形式传给父 Activity。
- 父 Activity通过重载该方法,就可以获取子 Activity 的返回值。
@Override protected void onActivityResult(int requestCode, int resultCode,Intent data) { super.onActivityResult(requestCode, resultCode, data); //在调用intent 对象 get<Type>()方法之前,还应该判断一下返回状态码和请求码是否正确。 if (resultCode == RESULT_OK && requestCode ==ACTIVITY1 ) { String name= data.getString(“name”); } }
五、Activity 启动模式
- Activity 启动 模式有 四种, 分别是: standard、singleTop、 singleTask、
singleInstance,可以在 AndroidManifest.xml 文件中通过给
标签指定 android:launchMode 属性来选择启动模式。
- standard
- 在没有指定情况下,所有 Activity 都默认使用 standard 启动模式。
- 对于使用 standard 模式的 Activity,系统不会在乎这个 Activity 是否已经在栈中存在,每次启动都会创建该 Activity 的一个新的实例。
- singleTop
- 在启动 Activity 的时候,如果栈顶已经是该 Activity,则认为可以直接使用,不会再创建新的 Activity 实例,否则则创建
- singleTask
- 每次启动 Activity 时,系统首先会在栈中检查是否存在该 Activity 实例,如果发现已经存在该 Activity 实例,直接使用该实例,并把位于该 Activity 之上的所有 Activity 出栈
- singleInstance
- 使用 singleInstance 模式的 Activity,会有一个单独的栈来管理这个 Activity,一般来说,这种模式是可以用来应用程序之间共享 Activity 实例,不管是哪个应用程序访问 Activity,都共用同一个栈。
- 例如,应用主 Activity 是 A,A 启动了 B,B 是 singleInstance 模式的,然后活动 B 启动了 C,点击 Back 键,会从 C 跳转到活动 A,因为 A 和 C 在一个栈,而 B是另一个栈,在点击 Back 键,A 跳到了 B,再点击 Back 键,退出程序。
附一、Activity生命周期
在 Android 系统中,采用 Activity 栈来维护和管理所有 Activity 组件,当 一个新的 Activity 创建时,它就会放到栈顶,位于栈顶的 Activity 就处于运行 状态。当再有一个新的 Activity 被创建后,会重新压人栈顶,而之前的 Activity 则会在新的 Activity 底下,就像枪梭压入子弹一样。而且之前的 Activity 就会 进入后台。当系统内存不足时,Android 系统会把位于栈底的 Activity 移除销 毁,被系统回收。因此,Activity 的生命周期是指从创建到销毁的过程。
生命周期类型:活动、暂停、停止、销毁
活动生命周期中的回调方法
onCreate(): 当 Activity 第一次被创建时调用。是生命周期开始的第一个方 法。
onStart():当 Activity 正在变为可见时调用。这个时候 Activity 已经可见 了,但是还没有获得输入焦点,不能跟用户交互。还在应用程序后台
onResume():当 Activity 可以接收用户交互时调用。于OnStart相比已处于应用程序前台
当 Activity 暂停时调用。在这里,可以用来保存数据,关闭动 画和其它比较耗费 CPU 的操作;但是这里绝对不能做耗时的操作,因为如果当前 Activity 要启动一个新的 Activity,新 Activity 会在当前 Activity 执行完毕 onPause()之后才能进入可见状态。 注意:在 Android3.0 之前,调用这个方法之后,Activity 可能会在系统内 存紧张时被系统回收。
onStop():当 Activity 进入后台,并且完全看不见时调用。在调用该方 法之后,系统在内存不够时可能回收该 Activity。
onDestroy():当 Activity 被销毁时调用,该是 Activity 生命周期中最后 一个调用方法。Activity 销毁原因:一般是程序中调用 Activity 的 finish() 方法销毁,二是系统在内存不足时系统主动销毁 Activity,以用来节省空间, 三是用户手动关闭Activity的界面。调用方法isFinishing()可以判断Activity 是否正被销毁。
onRestart():在 Activity 又重新回到可视状态时调用。 除了 Activity 生命周期回调方法以外,还有 onSaveInstanceState() 和 onRestoreInstanceState()两个方法经常会被使用,用来保存和恢复 Activity 的状态信息,例如用户在界面上输入的数据或选择的内容等
onSaveInstanceState():不属于 Activity 的生命周期方法,在 Activity 状态变化时,不一定会被触发。但是在应用遇到意外情况,比如:内存紧张,用户点击了 Home 键或者用户按下电源键关闭屏幕等,系统可能会销毁 Activity, 但该 Activity 在未来某个时刻还会显示在屏幕,这时 onSaveInstanceState() 方法会被调用。需要强调的是系统回收 Activity,而不是用户手动销毁 Activity。
onRestoreInstanceState(): 这个方法调用的前提是,Activity 必须是被 系统销毁了,在 Activity 被再次创建时它会在 onStart()方法之后被调用。
一般调用顺序onCreate()->onStart()->onResume()->onPause()->onStop()->onDestroy()
Gradle国内镜像
# 1.修改gradle-wrapper.properties文件:/gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-9.5.0-bin.zip
# 2.修改settings.gradle.kts文件这两项
pluginManagement {
repositories {
maven { url = uri("[https://maven.aliyun.com/repository/google](https://maven.aliyun.com/repository/google)") }
maven { url = uri("[https://maven.aliyun.com/repository/gradle-plugin](https://maven.aliyun.com/repository/gradle-plugin)") }
maven { url = uri("[https://maven.aliyun.com/repository/public](https://maven.aliyun.com/repository/public)") }
maven { url = uri("[https://jitpack.io](https://jitpack.io)") }
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven { url = uri("[https://maven.aliyun.com/repository/google](https://maven.aliyun.com/repository/google)") }
maven { url = uri("[https://maven.aliyun.com/repository/central](https://maven.aliyun.com/repository/central)") }
maven { url = uri("[https://maven.aliyun.com/repository/public](https://maven.aliyun.com/repository/public)") }
maven { url = uri("[https://jitpack.io](https://jitpack.io)") }
google()
mavenCentral()
}
}
# 3. 修改gradle.properties
# JVM内存,根据电脑内存调
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# 开启并行构建、缓存,加速编译
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configureondemand=true
# 需要代理时才加,不需要删掉
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=7890
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=7890
# 不走代理:localhost、国内镜像地址
systemProp.http.nonProxyHosts=localhost|127.*|maven.aliyun.com|mirrors.cloud.tencent.com
# 4.修改 %USERPROFILE%/.gradle/init.gradle
效果:打开任何Android项目,自动把google/mavenCentral/gradlePluginPortal替换阿里云,新建项目不用改代码
settingsEvaluated { settings ->
settings.pluginManagement.repositories.forEach { repo ->
if (repo is MavenArtifactRepository) {
val url = repo.url.toString()
when {
url.contains("dl.google.com") -> repo.setUrl("[https://maven.aliyun.com/repository/google](https://maven.aliyun.com/repository/google)")
url.contains("repo.maven.apache.org") -> repo.setUrl("[https://maven.aliyun.com/repository/central](https://maven.aliyun.com/repository/central)")
url.contains("plugins.gradle.org") -> repo.setUrl("[https://maven.aliyun.com/repository/gradle-plugin](https://maven.aliyun.com/repository/gradle-plugin)")
}
}
}
}
或者全局配置:
settingsEvaluated { settings ->
settings.dependencyResolutionManagement {
repositories {
// 阿里云镜像
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/google/' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' }
// 备用镜像
maven { url 'https://mirrors.huaweicloud.com/repository/maven/' }
mavenCentral() // 官方中心仓库(备用)
}
buildscript {
repositories {
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin/' }
}
}
}
}
- 其他资料
Android组件系列—-Intent详解 - 千古壹号 - 博客园 https://www.cnblogs.com/smyhvae/p/3959204.html
【干货】android中Adapter适配器的讲解 - 会飞的一只狼 - 博客园 https://www.cnblogs.com/huolan/p/5126794.html
【Android fragment实现多个页面切换效果_Android_脚本之家】 | https://m.jb51.net/article/138944.htm
【Android App中使用ViewPager+Fragment实现滑动切换效果_Android_脚本之家】 | https://m.jb51.net/article/81366.htm
【三种实现Android主界面Tab的方式 - caobotao - 博客园】 | https://www.cnblogs.com/caobotao/p/5103673.html