平台:

windows11

Android Studio 4.2.2
Build #AI-202.7660.26.42.7486908, built on June 24, 2021
Runtime version: 11.0.8+10-b944.6842174 amd64
VM: OpenJDK 64-Bit Server VM by N/A
Windows 10 10.0
GC: G1 Young Generation, G1 Old Generation
Memory: 4096M
Cores: 16
Registry: external.system.auto.import.disabled=true
Non-Bundled Plugins: com.intellij.ideolog, com.genymotion.idea, com.kite.intellij, org.jetbrains.kotlin

1.配置gradle,gradle的版本是越高越好。所以首先需要去获取gradle的最新版本,然后将他解压后放在一个比较好用的地方。

然后在Android studio中的

file----settings----Build Execution-Deployment----build tools ----Gradle

中设置,

上面的第一个框选择放入gradle的目录。

下面的适用于特定项目,对于任何一个项目,创建完毕即把 use gradle from 改为specific location 并选择gradle的目录是一个好习惯。可以减少下载错误,下载浪费,提高效率。

下载官方地址:Gradle | Installation

也可以问小伙伴要一份。

2.使用国内代理,用于下载依赖

在项目的build.gradle中添加,

maven{ url 'http://maven.aliyun.com/nexus/content/groups/public'}

(超越图片权限)推荐把这个放在respositories的第一行,这样或许会优先使用阿里云的国内镜像源进行下载依赖。事实上,这样会极大的提高依赖下载速度,尤其是网络不稳定时。

3.创建可靠的调试环境。(参考)

事实上,调试的速度很大程度上也决定了你的开发速度。当具备可靠的调试环境时,开发速度也会提升不少。

(1)一个经过测试较为稳固的虚拟机创建方案是

按如图方式以此选择,紧接着按照默认创建一个虚拟机。注意不要频繁操作。

(2)使用Genymotion.创建虚拟机。

这个相对来说比较稳定,但是对于Api较高的android系统的支持不是很好,而且也会有不稳定的情况发生。

事实上,如果方法(1)的虚拟机足够稳定,那么就选用第一个就好了,使用感受比第二种的虚拟机好。

如果出现虚拟机连接失败等错误,建议重启电脑。一般可以连接成功。

如果是出现 wait all 。。。to come online,这句话,可以适当等个30s如果还不行就删掉虚拟机,重启然后再新建一个虚拟机。

4.查看异常

在运行了一个app时,可以打开下方菜单栏的run来查看app运行的log和异常代码位置。(这点在处理程序异常退出,或者异常卡住等时查看报错信息,同时程序代码中的log函数的输出也在这里。)

event log则是用来查看android studio的log。

5.简述Android的Activity和Fragment与UI

(1)Activity与UI

给Activity分配UI

MainActivity.java

package cn.basicconstruction.example;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);TextView textView = new TextView(this);textView.setText("hello");setContentView(textView);Log.d("", "MMMMMMMMMM: "+textView);setContentView(R.layout.activity_main);}
}
run,可以看到程序正常运行,这也意味着,在运行时我们也可以通过函数调用来更改Activity的布局代码。事实上,我进行了尝试,成功了。这意味着setContentView这个函数,并不是在onCreate中能且仅能运行一次。而是可以运行多次。甚至可以取代多个Activity之间的跳转。但是这样也会带来空引用等问题。只能说是可以这么用,但是不推荐这么用。
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);TextView textView = new TextView(this);textView.setText("hello");setContentView(textView);Log.d("", "MMMMMMMMMM: "+textView);setContentView(R.layout.activity_main);Button button = findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener(){@Overridepublic void onClick(View view){setContentView(R.layout.activity_main2);}});
}
注意,第一个布局里面有一个按钮。
注意:在应用中使用Activity时需要在配置清单文件AndroidManifest.xml中注册。在配置清单文件中的application分支下添加一个新的activity标签。activity标签包含一系列元数据属性,如label,icon,permission,theme等。
没有对应的activity标签的Activity不能使用----启动时系那个会触发异常。
如果使用ide创建项目,则会自动配置mainactivity的配置清单。
再新建activity时需要自己注册。

(1)(3)Activity的状态--简述

a,活动状态—可见且拥有焦点的前台Activity

b,暂停状态---Activity虽然可见,但是却没有获得焦点。

C,停止状态----Activity不可见,但还没从内存中移出。

D,不活动状态----Activity被杀死。

(1)(4)生命周期

  1. onCreate

使用onCreate方法初始化Activity,初始化UI,如果Activity被运行时环境意外终止,onCreate方法将会传递一个Bundle对象,其中包括上次调用onSaveInstance方法保存的状态,当然这个保存状态的操作也可以用onRestoreIntstanceState来执行。

2.可见的生命周期

可见的生命周期发生在onStart和onPause两个处理程序之间。

onStop方法应该用于暂停或停止动画,线程,传感器,侦听器,GPS定位,计时器,Service或其他专门用于更新UI的进程。因为当UI不可见时,使用资源来更新UI没有任何价值。当UI再次可见时,我们可以使用onStart方法恢复或重新启动这些进程。

onRestart方法只有在第一次调用onStart的时候不被调用,之后每一次都会在onStart方法之前被调用。

3.活动的声明周期

活动的生命周期以onResume方法被调用开始,并在onPause方法被调用时结束。

活动的生命周期是指活动获得焦点到失去焦点的过程。

应尽量保持onPause和onResume方法中代码快速且轻量级,以确保应用在进入前台时马上响应。

如果系统确定可能需要恢复Activity的状态,那么再onPause调用之前立即调用onSavedInstanceState。这使得一个Activity的UI状态可以保存在Bundle,并进而传递给onCreate和onRestoreInstanceState.

使用onSavedInstanceState保存UI状态,可以确保Activity在下一次重新处于活动状态时能够呈现相同的UI。但有时系统也会决定不恢复当前状态,也会不调用onSavedInstanceState.

在 Android API 11后,onStop处理程序的完成标志着一个Activity不会在没有警告的情况下被终止。这使得我们应尽量的把耗时的操作转移到onStop方法中,使得onPause更加轻量。

MainActivity.java
package cn.basicconstruction.example;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {//onCreate方法只在Activity的生命周期中被调用一次,因此应尽可能把耗时的初始化操作置于此。super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overrideprotected void onRestart(){super.onRestart();//方法在第一次调用onStart的后时候不被调用,之后每一次都会在onStart方法之前被调用,可以用来实现仅当//Activity在完整的生命周期内重新启动时才需要执行的特殊处理。//在Activity进程进入可见状态时加载相应的变化。}@Overrideprotected void onStart() {super.onStart();//在可见的生命周期开始时调用}@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState){super.onRestoreInstanceState(savedInstanceState);//调用Activity最后被Android运行时(ART)销毁,然后启动。//而不是通过用户或程序操作(例如用户回击或调用finish()),//那么该方法会在onStart()方法结束后被调用。//从savedInstanceState中恢复UI的状态//这个bundle实例还会被传送到onCreate方法中。//那么该方法中onStart()方法结束后被调用。}@Overrideprotected void onResume(){super.onResume();//活动的生命周期开始时调用//恢复Activity所需的任何暂停的UI状态//但他们会在Activity处于不活动状态时暂停。//而在此阶段,Activity处于活动状态。//并接受来自用户操作的输入。}@Overrideprotected void onPause(){super.onPause();//活动的生命周期结束时调用//当Activity不在处于前台活动状态时,就会挂起不需要的Ui更新,//线程或CPU密集型操作。注意在多屏模式下,暂停的Activity可能仍然可见,因此应该继续所需的UI更新。}@Overrideprotected void onSaveInstanceState(Bundle savedInstanceState){super.onSaveInstanceState(savedInstanceState);//保存到savedInstanceState这个Bundle实例中,传递给onCreate和onRestoreInstanceState方法//在适当的时机被调用}@Overrideprotected void onStop(){super.onStop();//在可见的生命周期结束时调用//当Activity彻底不可见时,挂起不需要的剩余UI更新,线程或相应的处理。保存好所有的状态更改//因为Activity可能在onStop完成后的任何时候被终止}@Overrideprotected void onDestroy(){super.onDestroy();//有时在完整的生命周期结束时调用//清理所有资源,包括结束线程,关闭数据库连接等。}
}

(2)(1)Fragment和UI

Fragment使你能够将Activity划分为完全封装的可重用组件,每个组件都有自己的生命周期和状态。

每一个fragment都是一个独立的模块,Fragment可以包含UI也可以不包含,并且还可以在多个Activity中使用。封装了UI的fragment可以多种组合形式进行编排,以适应多窗格的UI,还可以在运行的Activity中执行添加,删除和交换等操作,以此帮助构建动态的用户界面。

在这里不在记叙Fragment的生命周期。

package cn.basicconstruction.example;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
public class ImgFragment extends Fragment {public ImgFragment(){};@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){return inflater.inflate(R.layout.fragment_img,container,false);}
}

【1】获取父activity的组件引用。

@SuppressLint("SetTextI18n")
@Override
public void onStart(){super.onStart();TextView tv = (Objects.requireNonNull(ImgFragment.this.getActivity()).findViewById(R.id.lt));tv.setText("hello world");TextView tb = (Objects.requireNonNull(ImgFragment.this.getActivity()).findViewById(R.id.button));tb.setText("hello world");
}

其中ImgFragment是该fragment的类。
【注意】
Fragment的创建生命周期发生在第一次调用onCreate方法和最后一次调用onDestroy方法之间。没有调用相应的onDestroy方法就终止进程的情况是很常见的,因此Fragment不能依赖于onDestroy事件的触发。
本来的用处:从父组件中分离该Fragment。
不可靠(不可依赖的情形):直接销毁Activity,直接终止APP。
【2】创建Fragment
和Activity相比,应该使用onCreate方法初始化Fragment,但是与Activity不同之处是,Fragment UI没有在onCreate方法中填充。
可以使用onCreateView方法初始化Fragment,膨胀UI并获取所包含的View的引用。
[3]Fragment manager
每一个Activity都有一个Fragment manager,用来管理它所包含的Fragment。在使用支持库时将使用getSupportFragmentManager方法来访问Fragemnt manager.
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentManager主要用于父组件(Activity)获取fragment的组件,比如
View view = fragmentManager.findViewById(R.id....);
FragmentManager还通过FragmentTransaction对Fragment执行添加,删除,和替换等操作。
本来FragmentManager实际上是一个抽象类,其中的方法并没有完全实现,而支持库的工厂函数返回的实例实际上是一个实现过的FragmentManager对象。
【4】将Fragment添加到Activity中,
(1)适用于 使用Fragment定义一组基于不同屏幕大小的静态布局。也就是嵌入这个fragment,并不打算对fragment这种View其进行删除,添加等操作。
在Activity的XML布局文件中包括一个fragment标签.
比如:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><TextViewandroid:id="@+id/lt"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:text="Hello World!" /><Buttonandroid:id="@+id/button"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Button"tools:layout_editor_absoluteX="148dp"tools:layout_editor_absoluteY="240dp" /><FrameLayoutandroid:id="@+id/frag"android:layout_width="match_parent"android:layout_height="wrap_content"/><fragment android:name="cn.basicconstruction.example.ImgFragment"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/f2" />
</LinearLayout>

橙红色部分,就添加了一个Fragment到Activity中,可以说是很轻便。
(2)通过容器来使用Fragment
在这里可把FrameLayout看作是一个最基本的View控件,既可代表Button这样的简单组件,也可代表fragment这样的复合组件。

ViewGroup类也继承自View类,它支持添加子类视图。

ViewGroup也是View.

这里的FrameLayout也可替换为其他ViewGroup。比如:LinearLayout,RelativeLayout等。
如上方青色部分。
Massive
/1使用Fragment Transaction
Fragment Transaction用于添加,删除和替换Fragment。使用Fragment Transaction,可以使布局具有动态性,也就是说,他们将根据用户交互和应用状态进行调整和更改。
每个Fragment Transaction可以包含受支持操作的任意组合,包括添加,删除和替换Fragment等。
可以使用Fragment Transaction地beginTransaction方法创建新的Fragment Transaction。在设置要显示地动画以及适当地后退栈行为之前,可根据需要使用add,remove,和replace方法来修改布局。当准备执行更改时,需要调用commit方法以异步方式将事务添加到UI队列中,或者使用commitNow方法阻塞线程,直到事务完全完成。

FragmentTransaction ft = fragmentManager.beginTransaction()

/2添加,移除和替换Fragment
在添加新的UIfragment时,创建并将新的Fragment实例以及放入容器View传递给Fragment Transaction的add方法,(可选)可以指定标记(TAG),以便以后使用findViewByTag方法查找Fragment。
添加ADD

FragmentTransaction ft = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frxx,new frxxx(param1),TAG);
fragmentTransaction.commitNow();

移出REMOVE

Fragment fragment = fragmentManager.findViewByTag(TAG);
FragmetTransaction.remove(fragment);
fragmentTransaction.commitNow();

替换REPLACE

FragmentTransaction ft = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frxx,new frxxx(param2),TAG);
fragmentTransaction.commitNow();

/3 Fragment和配置更改与Bundle
简单来说就是为了避免添加多个Fragment,让我们再次看一看这个 add方法(见上)。每次添加的是一个frxxx(param1).可能会在状态改变时再次添加一个Fragment导致UI布局发生改变。
<
为了在配置更改过程中保持一致的UI状态,在屏幕方向更改或意外终止后创建Activity时,将自动恢复添加到UI中所有的Fragment。
如果在onCreate方法中向Activity布局填充Fragment,则必须检查这些Fragment此前是否已经添加,以避免重复创建多个副本。
可以通过在添加Fragment之前检查它们,或者通过检查savedInstanceState变量是否为null来重新启动Activity。

ImgFragment imgFragment;
if(savedInstanceState == null){FragmentTransaction ft = fragmentManager.beginTransaction();ft.add(R.id.frag,new ImgFragment(),My_fragment);ft.commitNow();
}
imgFragment = (ImgFragment)fragmentManager.findFragmentByTag(My_fragment);

>
/4通过Fragment Manager获取Fragment。
///1将fragment借助xml文件添加到Activity布局中。
MyFragment myFragment = (MyFragment)fragmentManager.findFragmentById(R.id.MyFragment);
实例:

<fragment android:name="cn.basicconstruction.example.ImgFragment"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/f2" />
@Override
protected void onStart() {super.onStart();Log.d(tag, "onPause: Pause");ImgFragment imgFragment = (ImgFragment)fragmentManager.findFragmentById(R.id.frag);assert imgFragment != null;imgFragment.t2.setText("@t2");ImgFragment imgFragment2 = (ImgFragment)fragmentManager.findFragmentById(R.id.f2);assert imgFragment2 != null;imgFragment2.t2.setText("@t3");//在可见的生命周期开始时调用
}

为什么放在这里?
这是因为Activity的onCreate早于内嵌Fragment的onCreateView所以如果写在Activity的onCreate会出现空引用现象。而恰好这样可以,这说明了学习生命周期的重要性。
///2使用Fragment Transaction添加一个Fragment,查找Fragment容器View的资源标识符,

MyFragment myFragment = (MyFragment)fragmentManager.findFragmentById(R.id.view_in_activity_fragment_view);
部分见上(代码)
<FrameLayoutandroid:id="@+id/frag"android:layout_width="match_parent"android:layout_height="wrap_content"/>

///3也可以使用findFragmentByTag方法。
MyFragment myFragment = (MyFragment)fragmentManager.findFragmentByTag(TAG);
尤其适用于不含UI的Fragment。
/5 要删除给定方向布局中的Fragment容器,只需要在布局定义中将visibility属性设置为gone即可。

<FrameLayoutandroid:id="@+id/frag"android:layout_width="match_parent"android:visibility="gone"android:layout_height="wrap_content"/>

/6Activity与Fragment之间的通信。
Activity: MainActivity
Fragment: ImgFragment 实例 imgFragment
\\\context
在MainActivity.java中调用imgFragment.getContext()与在ImgFragment的onAttach(Context context)中传给这个函数的context是一个context也即父Activity的context。也与在Activity中调用
this是一样的。toString()均为:
cn.basicconstruction.example.MainActivity@69db4f(特定情况,实例)
\\\View

<1>获取父Activity组件引用
在Activity中可以使用(this.)findViewById(R.id.xxx)组件。
在Fragment中使用getActivity().findViewById(R.id.xxx)可以获取弗雷德组件。
<2>获取子Fragment组件引用
在Activity中使用fragmentManager.findFragmentById/Tag(xx).getView().findViewById(R.id.xxx)可以获取到Fragment(含UI)的组件的引用。
<备注如果出现失误,
这样用 ImgFragment imgFragment = fragmentManager.findFragmentById/Tag(xx);
Button bt = imgFragment.getView().findViewById(R.id.xxx);
>
在Fragment中在onCreateView中使用

View view = inflater.inflate(R.layout.fragment_ui,container,false);
Button bt = (Button)view.findViewById(R.id.xxx).

事实上,基于这个也可以使用this.getView().findViewById(R.id.xxx);
这个是由Fragment.getView().findViewById(R.id.xxx)获得启发。但是这个getView()获取需要在onCreateView()完成之后。可以在onStart等方法中使用。
可以获取到Fragment的组件的引用。在onCreateView()中使用this.getView().findViewById(xxx)会因为程序异常而导致空引用。空引用是指getView()获得的引用是空的,因为还没有初始化View,或者getView()函数依赖于onCreateView()返回的View。
last:
没有UI的Fragment。
因为Fragment没有UI,所以他不将于容器View相关联,于是就可以忽略掉R.id.xxx这个参数.[在这里拷贝之前的代码进行更改]

ImgFragment imgFragment;
if(savedInstanceState == null){FragmentTransaction ft = fragmentManager.beginTransaction();ft.add(new ImgFragment(),My_fragment);ft.commitNow();
}
imgFragment = (ImgFragment)fragmentManager.findFragmentByTag(My_fragment);
由于太长的文本会使得阅读和建立目录变得困难,故在这里分页。

参考:ISBN 978-7-302-53952-0 Android高级编程  Professional Android,Fourth Edition.

Android开发帮助技巧(适用于入门)(第一部分-高效地构建项目的准备工作和Activity与Fragment的交互介绍)相关推荐

  1. Android Studio新手–下载安装配置–零基础入门–基本使用–调试技能–构建项目基础–使用AS应对常规应用开发

    转自:http://blog.csdn.net/yanbober/article/details/45306483 目标:Android Studio新手–>下载安装配置–>零基础入门–& ...

  2. android开发可用技巧

    android开发可用技巧 都是本人在android开发的学习过程中用到的小技巧,记录于此,便于以后查找 获取屏幕尺寸 DisplayMetrics dm = getResources().getDi ...

  3. Android开发小技巧 | 一句命令搞定截屏

    -- 简书作者 谢恩铭 转载请注明出处 一句命令搞定截屏 在安卓开发中, 我们很多时候都要用到截屏这个功能. 有时是为了演示, 有时是为了报告问题(比如在Bugzilla, Jira, Redmine ...

  4. Android 开发小技巧 | 一句命令搞定截屏

    -- 作者 谢恩铭 转载请注明出处 一句命令搞定截屏 在安卓开发中, 我们很多时候都要用到截屏这个功能. 有时是为了演示, 有时是为了报告问题(比如在Bugzilla, Jira, Redmine等B ...

  5. Android开发-小技巧汇总2

    启动虚拟机时,在 launch options 窗口中 有个 wipe user data ,勾选它,将会让虚拟机 [恢复出厂设置] 2.[如果想让自己的应用程序有多个启动图标:] 为一个应用的 多个 ...

  6. Android开发环境搭建与入门Hello World

    一直没机会接触手机开发,很想开发一款手机围棋软件,今天先学习一下环境搭建与Hello World吧. 环境配置对于没入门的很麻烦,谁如果有需要留下QQ邮箱,我发给你.不客气,呵呵. 推荐一本书: Go ...

  7. Android 开发小技巧(2)

    转自:农民伯伯: http://www.cnblogs.com/over140/ 常用代码 7.1   在当前Activity中启动另外一个Activity startActivity(new Int ...

  8. android开发小技巧:实现listview异步加载图片

    2019独角兽企业重金招聘Python工程师标准>>> 针对listview异步加载图片这个问题,麦子学院android开发老师讲了一种非常实用的方法,麦子学院android开发老师 ...

  9. NXP KW38蓝牙开发(一)入门第一课:官网蓝牙广播和连接例程,NMI禁止

    首先要下载开发使用的IDE:MCUXpresso IDE 下载链接: 进入nxp的官网,搜索KW38 向下翻看,找到Xpresso,点击进入 习惯使用IAR开发的同学也可以下IAR版本,这里以Xpre ...

最新文章

  1. python学习——01循环控制
  2. python读取excel表格-Python读取Excel单元格的内容
  3. SpringBoot的端口配置server.port没办法设置成Linux的环境变量
  4. java 编写代码_Java 7:如何编写非常快速的Java代码
  5. linux的oracle修改实例名SID
  6. 国潮国粹剪纸风京剧人物PSD素材,让东方韵味更浓
  7. 关于Mysql8.0.26版本与IDEA连接的配置
  8. sql中的distinct
  9. Go的package学习
  10. ①管理员身份运行cmd;②cmd命令切换到指定文件夹目录;③cmd命令窗口中复制粘贴
  11. word文档字体段落文档格式标准设置(个人)
  12. Setup Factory 点击uninstall.exe Invalid start mode : archive filename
  13. 嗨格式视频转换器全新上线,一个音视频转换神器
  14. 一起找BUG,谷歌推出全新漏洞悬赏平台
  15. 世界五大黑客:代码创造他们,他们改变世界!
  16. “新产业50人论坛”之清华龙桂鲁教授:量子信息与创新发展
  17. xtrabackup全量+增量备份
  18. 基于Orangpi Zero和Linux ALSA实现WIFI无线音箱(二)
  19. HC05主从一体化蓝牙模块配置
  20. 成为跨领域的「解决方案架构师」需要什么素养?

热门文章

  1. ABB 5SHY3545L0016 IGCT模块
  2. 解决Mac下Office World快捷键不能使用问题
  3. android epg界面实现,一种EPG引擎及页面解析方法与流程
  4. QT 系统学习 day06 ,摄像头,语音识别(语音转文字,文字转语音,Qt 的人脸识别系统),
  5. docker tcp6改为tcp_Docker deamon监听tcp端口设置
  6. 对stdin,stdout 和STDOUT_FILENO,STDIN_FILENO的学习
  7. MMI在ASR中的应用
  8. 执行python命令和脚本文件_执行python脚本文件的方法
  9. Materials Studio 2021新版本发布|达索系统®
  10. 【CodeForces】Codeforces Round 616