记录遇到的问题和新的知识篇

1. 2个onCreate() 方法的区别

在Activity的onCreate() 方法有2个 一个protected(受保护的) 另一个是public(公开的)

这里怎么会有两个onCreate提供给我们重载?选择困难症患者表示根本选不出来。WTF?长久的经验告诉我们,我们要重载的是第一个onCreate方法,他只有一个参数也一直只有一个参数。并且用protected进行约束。

二个方法的区别:

我们知道onCreate 是Activity生命周期的第一个方法。我们通常会在onCreate中做一些View初始化,等等操作
onCreate在整个生命周期只会初始化一次外,他还有一个很重要的作用:当我们的Activity非正常销毁之后,

例如手机旋转,内存不足导致的后台自动销销毁。为了保护我们的数据可以将数据保存在savedInstanceState中,
当Activity重启数据依旧不会消失。我们可以通过onCreate方法中的savedInstance参数拿到我们的数据。

做法很简单只要重载onSaveInstanceState或者onRestoreInstance就可以了
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
}

将数据以键值对的形式传入,方法提供一个Bundle类型的outState参数暂存数据。之后再onCreate中取出,
保证Activity销毁但是数据不销毁。真是简单实用的功能解决了大多数手机内存不足而用户前台数据丢失的痛点。

onCreate方法以及足够强大,但是他能否更加强大?有没有这样一种情况,手机由于过热,没电或者第三方定制
下面介绍onCreate的第二个方法

@Override
public void onCreate(@Nullable Bundle savedInstanceState,
 @Nullable PersistableBundle persistentState) {
      super.onCreate(savedInstanceState, persistentState);
  }

当你的手机异常关机,他能帮你找回之前前台的数据。他实际上是一种数据持久化的Activity

使用方法:
我们需要在Android 的清单文件的Activity中指定如下属性:
android:persistableMode=”persistAcrossReboots”

接着重载onSaveInstanceState或者onRestoreInstance:

@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
    }

@Override
public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState) {
        super.onRestoreInstanceState(savedInstanceState, persistentState);
}

他们对应着一个PersistableBundle类型的persistentState。对齐进行操作就OK了。

补充:上面说到重载onSaveInstanceState或者onRestoreInstance。这里解释一下这两个方法onSaveInstanceState调用时机是当前Activity即将被销毁而还未被销毁的时候。而当系统调用了onRestoreInstance就表示这个Activity已经被销毁了。这个可以看需求

进行调用,这里补充一下知识点。

2.setContentView

setContentView
下面的代码是每一个Androider最熟悉的了,初学者在建立新的Acitivity的时候很任意忘记这一句
导致运行报错

3. 给文本内容加滚动条

给文本内容加滚动条
TextView tv;

tv.setMovementMethod(ScrollingMovementMethod.getInstance());

4.public 关键字

我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立。
然而在某些时候,我们更希望该类所有的对象共享同一个成员。此时就是 static 大显身手的时候了

     Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,
     即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问。  
     当然,鉴于他作用的特殊性更推荐用类名访问
     使用 static 可以修饰变量、方法和代码块。

我们在类中定义了一个 静态变量 hobby ,操作代码如下所示:

这里写图片描述

要注意哦:静态成员属于整个类,当系统第一次使用该类时,就会为其分配内存空间直到该类被卸载才会进行资源回收!

5.关于Activity声明周期

  • 从一个ActivityA跳转到另外一个ActivityB后,在返回后,ActivityA的生命
1.ActivityB如果为透明或者窗口化,那么将执行onPause-onResume
2.ActivityB是全屏的,并非透明,那么将执行onPause-onStop-onRestart-onStart-o
nResume
3.ActivityA因内存不足被回收,那么会执行onPause-onStop-onDestory-onCreate-on
Start-onResume
  • 如何安全的退出已调用多个Activiy的Application
循环遍历退出用的最多,在Activity打开时记录,并在需要退出时,遍历所有Activity,并
调用finish方法。
2.  其他还有抛异常退出,使用startActivityForResult方法进行连续判断退出,杀进程以及杀
死主线程等方法。
  • 横竖屏切换时Activity的生命周期
    设置 android:configChanges="orientation" 和不设置这个属性,这两个效果
是一样的,activity都是重新创新.
    横屏切竖屏,以及竖屏切回横屏,这两个也是一样的(如下总结),不会出现网上说的横
屏切回竖屏时,生命周期执行两遍的问题.
        重新创建activity的生命周期
    2.3上:onSaveInstanceState->onPause->onStop->onCreate-
>onStart->onRestoreInstanceState->onResume
    4.0上:onPause-
>onSaveInstanceState->onStop->onCreate->onStart->onRestoreInstanceState
->onResume
    不重新创建activity,只会调用 onConfigurationChanged
    targetSdkVersion会影响生命周期,targetSdkVersion在12及以下的话,
设置了 android:configChanges="orientation|keyboardHidden" ,在机器上都不会
重新创建activity,只会调用 onConfigurationChanged,如果设置targetSdkVersion
>12的话,只在sdkVersion<=12的机器上有效果,>12的机器上activity还是会重新创建(
需要加上screenSize才有效果)
    android2.3和android4.0的生命周期不一样,2.3是
先onSaveInstanceState,后onPause,4.0是先onPause,后onSaveInstanceState(
)
  • 总结:
    设置 android:configChanges="orientation" 和不设置这个属性,生命周期表
现为重新创建activity

    设置 android:configChanges="orientation|keyboardHidden",在2.3上表现为
不重新创建activity,4.0如下
    android:targetSdkVersion<="12",生命周期表现为不重新创建activity
    android:targetSdkVersion>"12",表现为重新创建activity
    3.设置 android:configChanges="orientation|keyboardHidden|screenSize",
在2.34.0上都表现为不重新创建

6.如何在不失真的条件下显示一张超高清的图片或者长图?

1.通过计算BitmapFactory.Options对象的inSamleSize值 等比压缩图片
2.使用WebView来加载图片
3.使用MapView或者TileView来显示图片(类似地图的机制)
4.BitmapRegionDecoder局部加载(不过影响用户手势加载不同区域是个难点)

7.关于ScrollView内嵌套ListView的bug

scrollview里面嵌套listview的坑
scrollview里面嵌套listview是一种很不好的做法,最好还是使用一个listview,将其他需要滑动的部分添加为头布局脚部局,或者在adapter里面将头脚用一个标志位去判断作为单独的item,这样性能是最完好的,不容易出现bug。

当然了,难免有人会用到的,会出现只显示一个item的bug,解决办法有两种。一种是自定义一个WrapContentListview,很简单的继承自Listview,只需要重写OnMeasure方法

public class WrapContentListView extends ListView{
    public WrapContentListView(Context context) {
        super(context);
    }

    public WrapContentListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public WrapContentListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

改成这样就可以

8. android:descendantFocusability用法简析

开发中很常见的一个问题,项目中的ListView不仅仅是简单的文字,常常需要自己定义ListView
自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题就出现了
可能会发生点击每一个item的时候没有反应无法获取的焦点。原因多半是由于在你自己定义的Item中
存在诸如ImageButton,Button,CheckBox等子控件
(也可以说是Button或者Checkable的子类控件),此时这些子控件会将焦点获取到,
所以常常当点击item时变化的是子控件item本身的点击没有响应。

这时候就可以使用descendantFocusability来解决
该属性是当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系。

  • 属性的值有三种:

    beforeDescendants:viewgroup会优先其子类控件而获取到焦点

    afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点

    blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点

这里写图片描述

  • ListView使用如下:
    这里写图片描述

9.TextView在代码中用Html标签设置一行字体显示不同的颜色

同一行字 不同颜色 可以用html标签
String statusHtml = String.format
(Locale.CHINA, "状态:<font color=#21bd5f>%s</font>", status2statusName(item.getStatus()));
TextView statusView = helper.getView(R.id.tv_apply_for_status);
statusView.setText(Html.fromHtml(statusHtml));

10.在提交数据时对提交Button或者TextView的优化 防止用户过度点击

在提交数据时 Button会改变状态 显示提交中
submitBtn.setEnabled(networkState.getStatus() != NetworkState.Status.RUNNING); 
submitBtn.setText(networkState.getStatus() == 
NetworkState.Status.RUNNING ? "提交中...": getString(R.string.submit));

11.使用Handler 实现定时器

new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                switch (par) {
                    case 1:
                        callback.onSuccess("加载成功");
                        break;
                    case 2:
                        callback.onFail("加载失败");
                        break;
                    default:
                        callback.onError();
                        break;
                }
                //结束
                callback.onComplete();
            }
        //延迟两秒执行
        }, 2000);

12.java中split()特殊符号”.” “|” “*” “\” “]”

关于点的问题是用string.split("[.]") 解决。
关于竖线的问题用 string.split("\\|")解决。 
关于星号的问题用 string.split("\\*")解决。
关于斜线的问题用 sring.split("\\\\")解决。 
关于中括号的问题用 sring.split("\\[\\]")解决。

13.TextView文本属性

这个属性用来显示一行文字有很多的情况下 后面显示不了的用省略号代替
android:ellipsize="end"
一般可以配合
android:maxLines="1"

14.关于double值保留两位小数的问题

 //这里是获取的默认值 可能是整数也可能是一位小数 和自己设置有关
 public double getGoodsRealPrice() {
        return goodsRealPrice;
    }

    //在下面可以写一个保留两位小数的方法 然后应用!
    public String doubleToString() {
        return String.format(Locale.CHINA, "%.2f", goodsRealPrice);
    }

15.两个并排TextView 字体大小不一致 要求按照字体底部对齐

用ConstraintLayout的属性
 app:layout_constraintBaseline_toBaselineOf="@+id/money_sign"
 money_sign是要对齐组件的Id

未完待续

猜你喜欢

转载自blog.csdn.net/life_s/article/details/79560008