欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

前阶段的Android学习总结

程序员文章站 2022-06-09 08:55:38
...


半年一更新,一更拖半年……前阶段直至在“不踏实”地学习Android知识;跟了不少视频,看了不少书;实际上学地都不踏实;直到今天彻底迷茫,不知道该怎样“系统地”学习Android;我想那不如把前阶段的收获总结分享一下吧:

如果你从中有所收获的话,请给我点个赞鼓励下吧!????

一、Android Studio导入现有工程的几个步骤

这里是参考的:“Android Studio导入现有工程的几个步骤.”
概括以下四步:

  1. 根目录下的 build.gradle里定义了gradle tool的版本号;手动修改这里的版本号为当前支持的版本号:
  2. 根目录下的gradle\wrapper里的gradle-wrapper.properties文件修改为自己的gradle配置中的zip包的版本;
  3. 最后修改一下app模块下的build.gradle;对应的sdk的版本,build tool的版本号,以及一些依赖的jar包;
  4. 如果Android studio运行出错 compilation failed see the compiler error output for details.;点击下图圈圈;切换一下显示模式;就可以具体修改代码中的错误;前阶段的Android学习总结

二、这里推荐一篇好文

这篇文章里有不少经验分享和资料分享: Android小白学习成长路线.

三、四大应用组件之ContentProvider

不知道这里为什么会有这篇经验;如有侵权,请联系我立即删除!

  1. 理解
    1). 为会么要有ContentProvider?
    前阶段的Android学习总结
    2). ContentProvider是什么?
    前阶段的Android学习总结

  2. 相关API:

    1). ContentProvider: 内容提供者类
    前阶段的Android学习总结
    2). ContentResolver: 内容解析器类 :
    前阶段的Android学习总结
    3). Uri: 包含一个具有一定格式的字符串所对应资源的类
    前阶段的Android学习总结
    4). UriMatcher: 用来识别uri的一个uri容器
    前阶段的Android学习总结
    5). ContentUris: 操作uri的工具类
    前阶段的Android学习总结

  3. 自定义ContentProvider
    前阶段的Android学习总结

  4. 使用ContentResolver访问ContentProvider
    前阶段的Android学习总结

  5. 应用练习

    1). 使用 ConentResolver 查询得到所有联系人数据列表
    2). 使用 ListView + BaseAdapter 显示列表
    3). 使用带回调启动 Activity 和带结果的返回

四、Git

  1. 期间里用一周时间了解了一下Git;
  2. 学习资料当然是“业界公认"的: 廖雪峰的官方网站.
    我打起了广告?额……不管了,自己的学习总结而已;

五、View学习总结和BUG

  1. ListView

    • 设置一个ListView并找到;
    • 初始化数据(把数据装到集合里);
    • 数据设置到adapter中;
    • adapter 又设置给ListView;
    • 难点在于自定义adapter
      a. 自定义adapter继承与ArrayAdapter<或BaseAdapter>;并产生其构造器;
      b. 重写 .getView() ;此时 ListView 中每一个项目可用 .getItem() 获得;
      c. 其中重写了一个 ViewHolder 类;
      d. 难点 在于两步优化和 .getView() 的理解。
    • BUG:判断 ArrayList 中是否为空;绝不能用 mFruitList == null;
      要用 mFruitList.size() == 0 代替

    疑问:"com/example/listviewtest/FruitActivity.java:25"中;去重方法 写了;可是,每次打开软件都是重新填充数据,而不会用到去重方法。.

  2. BUG :List 使用 add 方法时;List集合add方法覆盖原来的内容 ;修改 用 addAll 复制得到的数据 arrayList 中 ,修改数据时,原数据也被修改;结果就是,最终添加的结果都一样,全都是最后一次add的效果,<都是Java基础不扎实的原因啊>
    a. 这是因为,arrayList 的性质!如果元素是引用类型,保存的是引用,如果是值类型,保存的是值本身。这里addAll 只是复制了地址,并非复制了全部的元素!同理,数据的add(),可以在set()前,也可在其后;
    b.解决方法:就是每次循环的时候,都把要添加的对象, new 一遍然后进行 set 等操作;如果元素是 值类型 ,那么就不许重复 new 对象;
    c. 那么如何复制 集合中的元素!还是老老实实的遍历吧……

  3. BUG

    Android报错:Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)
    Caused by:
    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
    

    解决方法
    1. 根据提示找到出错行;
    2. xml 布局文件中,id不能大写
    3. 资源名不能大写!
    4. 控件名称首字母要大写:< V iew
    5. View划横线:用的是 background

    如果你从中有所收获的话,请给我点个赞吧!????

六、fragment 和 Framelayout

学习资源来自 郭神《第一行代码Ⅱ》4.2.2 动态加载碎片 P148
原图如***意右边半拉):
前阶段的Android学习总结
设置了点击事件,当点击button时,会动态载入碎片:
main_activity.xml 使用 <FrameLayout 布局时,得到的是正常的结果:前阶段的Android学习总结
如果使用 fragment 碎片;得到的结果没有用新界面完全代替就界面,如下:前阶段的Android学习总结
原因:
a. 因为默认的这层 right_fragment,使用的 linear layout 填充的,而这个layout里面只有一个text view,当你设置的点击事件直接使用碎片 fragment ,来动态加载碎片时,就只能在这个textview之下。
b. 要想动态加载碎片,就必须用另一个 FrameLayout 替换 LinearLayout,而后往 layout 中填充碎片。到此问题解决。

七、关于广播接收器的注册销毁

学习资源来自 郭神《第一行代码Ⅱ》5.5 最佳实践 P190 下

关于广播接收器的注册和销毁

  1. 广播接收器都是在 .onCreate() 中注册,在 .onDestroy() 中销毁;
  2. 但是本次实例,是要接受一个,强制下线的广播,只需要保证:处在栈顶位置的活动能接收到广播,非栈顶活动不需要接受;
  3. 所以本处用到了 activitycollect 和 BaseActivity 写的十分巧妙;来看一下 activity 的生命周期前阶段的Android学习总结

八、一些小的注意事项

  1. 代码顺序,由上而下一定要有逻辑,.findViewById() 一定要先写,不然程序闪退。

  2. 学习存储的时候,因为无法使用DDMS查看手机的文件,而大费周章,原来就在 AS右下边有一个竖条形的键,就是打开文件存储的快捷方式。

  3. manifest 中申请权限;一定要加 uses- uses- permission android:name=“android.permission.READ_CONTACTS”

  4. BUG :关于 String 判空

    错误: if (mResponseData.equals(null) || mResponseData.length() == 0) {
    正确: if (mResponseData == null || mResponseData.equals("")) {
    或者: if (!TextUtils.isEmpty(restoreText)) {
    
  5. 真机安装 apk 失败;在 gradle.properties 文件添加一句 android.injected.testOnly = false

  6. java生成随机数有两种方法:

    1、使用Math方法,
        int num = (int) (Math.random() * 15);
    	(int) (Math.random() * num) 	//生成的是 0 ~ num-1
        (int) (Math.random() * num + 1) //得到的是 1 ~ num
    2、使用Random方法,
        Random random = new Random();
        int length = random.nextInt(20) + 1;
    
  7. 自定义控件使用:

    a. 编写 title.xml 文件;
    b. 编写自定义控件 类 在构造器中引入.xml
     	LayoutInflater.from(context).inflate(R.layout.title, this);
    c. 在需要引用自定义控件的 xml 中引用(LinearLayout);
    	<com.example.myapplication200122.TitleLayout
    				...
    
  8. 碎片的使用:

    a. 编写布局 fragment.xml; 
    b. 编写碎片 类 ;.onCreate() 中使用 .inflate() 将碎片布局引入;
      View view = inflater.inflate(R.layout.fragment, container, false);
    c. 在需要使用碎片的 xml 中使用:
        <fragment
            android:name="com.example.fragmenttest.LeftFragment"
                    ...
    
  9. View 和ViewGroup 的区别
    首件删除了笔记,现场直编……

    1. 如果点击事件出问题,不响应或者响应其他控件时;应该 检查 xml 的布局,是否控件被覆盖;
    2. View 不能对其子空间进行操作,而 ViewGroup 可以,所以如果出现,动画已经从页面消失,而仍然响应点击;可以考虑
      a. 把 View 更改成 ViewGroup ,然后遍历其子控件,当子控件消失设置其不可点;
      b. 或者使用 属性动画(ObjectAnimator) 代替 值动画;
  10. Android编译出错:app:checkDebugDuplicateClasses;检查是不是依赖包重复了;

九、数据库学习中遇见的BUG

  1. 先看代码:

    报错:org.litepal.exceptions.DatabaseGenerateException: can not find a class named com.coolweather.android.db.Province
    
    问题在于:数据库知识掌握不扎实;litepal.xml 文件中结构。如此 stupid 问题……
    <litepal>
    <dbname value="cool_weather" />
    <version value="1" />
    <list>
    <mapping class="com.example.coolweather.db.Province" />    //放数据库所在 包名
    <mapping class="com.example.coolweather.db.City" />
    <mapping class="com.example.coolweather.db.County" />
    </list>
    </litepal>
    

    这是因为数据库中定义的名称和 .java 文件中名称不一致,找不到;

  2. 学习资源来自 郭神《第一行代码Ⅱ》14.5.3 将天气显示到界面上 P520

    报错:Attempt to read from field 'java.lang.String com.example.coolweather.gson.Basic.cityName' on a null object reference
    java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.example.coolweather.gson.Basic.cityName' on a null object reference
    

    这是因为:在JSON中的一些字段可能不太适合直接作为java字段来命名,因此使用了 @SerializedName 注解的方式来让JSON 字段和Java字段之间建立映射关系;而JSON的数据是键值对的格式存在的,我们在Json格式文件中写的 键,和java文件中的取值 键 不对应;所以无法获取到对应的值。

十、inflate 方法

  1. 介绍
    LayouInflater 中 inflate 方法两个参数和三个参数
    LayoutInflater.from(RecylerActivity.this).inflate(R.layout.my_text_view,viewGroup,false);
    View.inflate(RecylerActivity.this, R.layout.my_text_view, null);
    
  2. 如果我们采用 convertView = inflater.inflate(R.layout.item_list, null);方式填充视图,item布局中的根视图的layout_XX属性会被忽略掉,然后设置成默认的包裹内容方式;
  3. 如果要保证item的视图中的参数不被改变,我们需要使用convertView = inflater.inflate(R.layout.item_list, parent,false);进行填充;
  4. 除了这种方式,我们还可以设置item布局的根视图为包裹内容,然后设置内部控件的高度等属性,这样就不会修改显示方式。
    总之推荐用inflater.inflate(R.layout.item, parent, false);
    关于这节内容你应该是看不懂,推荐你看: inflate方法两个参数和三个参数的区别;.

如果你从中有所收获的话,请帮我点赞收藏分享鼓励我吧!????

相关标签: Android学习总结