Android伍什小随笔(一)

386 阅读16分钟

1.Token

  首先Token是一个怎么样的东西,Token存在的意义又在哪里?学过php或是其他web开发的人都知道一个东西叫session和cookie,这些东西可以在服务器或是本地保存一些东西,比如说登录状态,当用户登录后可以通过session或是cookie在本地保存一段时间的登录状态,在这段时间内,用户再度登录的时候就不用再输入用户名和密码了,但是过了一段时间后,用户需要再次进行身份认证,这样一来的话,一方面节省了很多操作的步骤提升了操作体验,同时也节省了很多服务器请求,提高了服务器性能,同时也保证了一定的安全性。

  那么这个功能如何在android中实现呢?很可惜的是在android中并没有直接提供类似session或cookie的东西,这个时候就是通过Token来完成。Token的存在更像是一个令牌,比如说当我们需要实现具有用户权限的操作时,每一次操作都需要向服务器发送请求,让服务器完成在数据库中进行用户名和密码,这些显然对于服务器的性能是很不利的。当然有人也会说我们可以在一次请求成功后将类似于user_id的东西保存在本地,以后每次请求的时候用user_id进行操作,这样不是就降低了服务器的负担,但是这样的话存在一个问题,就是user_id一旦存储在本地的时候,不是太有可能会自动回收掉,这样一来的话就会导致一个问题,就是app无论何时打开都是验证通过的状态,这样一来安全性降低。而Token就是解决这样一个问题的东西:

Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。

2.Throwable:所有已实现的接口

3.key-value 键值对 和4绑定讲解

  • key 需要存的值的编号 Token
  • value 需要存放的数据 dhjwejrdgwjefhjqtwjkawlfi8a34

4.CacheUtil缓存工具类

CacheUtil中的存取方法

具体使用方法--LoginActivity

  • 在 “登陆”按钮的点击事件中传入

【注意⚠️】

如果 “类.方法”的时候,方法出不来,那就说明,该方法还没有被定义为静态类,还不可以被调用。那就需要返回工具类中,将该方法改为静态类的

CatheKey.TOKEN -- RetrofitFactory--自定义网络拦截器--获取本地缓存的token

  • getInstance()--外部获取实例对象
    • 在 TaskGoApplication.java文件中

  • CatheKey.java

5.面向对象

原网址:https://www.cnblogs.com/dotgua/p/6354151.html?utm_source=itdadao&utm_medium=referral

1.extends与implements

  • 一个子类只能拥有一个父类->类的继承是单一继承
    • extends只能继承一个类
  • implements实现多继承特性,继承多个接口
    • 接口与接口之间采用逗号分隔

2. super与this

  • super:实现对父类成员的访问,用来引用当前对象的父类
  • this: 指向自己的引用
class Animal {
  void eat() {
    System.out.println("animal : eat");
  }
}
 
class Dog extends Animal {
  void eat() {
    System.out.println("dog : eat");
  }
  void eatTest() {
    this.eat();   // this 调用自己的方法
    super.eat();  // super 调用父类方法
  }
}
 
public class Test {
  public static void main(String[] args) {
    Animal a = new Animal();
    a.eat();
    Dog d = new Dog();
    d.eatTest();
  }
}

输出结果:

animal : eat
dog : eat
animal : eat

3.final和static

  • final
    • 将类定义为不可继承的,即:最终类
    • 或用于修饰方法,表明该方法不能被子类重写
    • 变量加final就变成常量,不可被改变

【注】: 1.被final定义的类和这个类里面的变量是两回事,final定义类的时候,对类里面的变量没有任何影响,调用final类的方法对变量也没有任何影响 2.被声明为final类的方法自动的声明为final,但实例变量并不是final

  • static修饰成员变量 + static关键字可以修饰成员变量和方法,来让它们变成类的所属,而不是对象的所属(对象是类的实例),解释👇
public class Person {
    String name;
    Int grades;
    static int class;
}

实例化 20个Person对象,那就有了40个不同的 name 和 grades
但是  全全部部只有一个 class
  • static修饰成员方法
    • "类名.方法名"调用该静态方法
如果在一个类中,某方法不是静态方法(非static修饰),那就不可以通过"类.方法"进行调用
  • static修饰静态块
    • 创建对象时,static修饰的成员会首先被初始化
      • static修饰的成员变量首先被初始化,随后是普通成员,最后调用类的构造方法完成初始化

4. 重写与重载

  • Overloading
    • 方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载
  • Overriding
    • 方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写
  • 方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现

5.多态和虚方法

安卓多态运用--自定义图形:http://blog.csdn.net/qq_32985981/article/details/50173503

6.封装--对数据的隐藏

  • 控制那些是自己所私有,哪些可以被共享使用
  • 外部用户只需要关心该类的功能和对象,不需要关心具体的实现过程和数据

7.Path 和Query

  • 有问号的使用Query
  • 只有 {...} 的使用Path

8.为了缓存新用户的Token

是想注册的接口后 调用 登录接口

因为Token的保存是在登录的接口上

9.线程问题

  • 由于等用户注册后直接进入主界面,不需要再次进进行登录界面的相关操作,但是Token只能在登录的时候进行本地缓存,所以⚠️⚠️,我们就可以在注册界面 再一次 调用登录的接口

坑:两个接口的调用,不能同时进行,不然开启就是两个线程同时进行,导致 一边Toast出来“此用户不存在”,一边 又直接进入了主界面

廖雪峰线程章节

1. 多线程

  • 多线程:让任务交替执行
  • 一个进程可以包含一个火多个线程
  • 多进程稳定性比多线程稳定性高
    • 一个进程的出问题,不影响其他进程
    • 一个线程出问题,其他线程也会死

2.创建新线程

  • 程序本身无法控制线程的先后顺序
  • 必须使用 start() 方法才能启动新线程
  • Thread.sleep()可以把当前线程暂停一段时间

8.Bundle

  • 一种存放字符串等类型数据的map类型的容器类
  • 通过存放数据键(key)获取对应的各种类型的值(value)
  • 主要作用于Activity之间的数据传递

9.JAVA接口

1.接口与类的区别

  • 接口不能实例化对象
  • 接口没有构造方法
  • 接口中所有的方法必须是抽象方法
  • 接口不能包含成员变量,除了static和final变量
  • 接口不是被类继承的,而是要被类实现的
  • 接口支持多继承

2.接口特性

  • 接口中的方法会被隐式的指定为public abstract
  • 接口中的变量也会被隐式的指定为public static final 变量
  • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法

3.抽象类与接口

  • 一个类只能继承一个抽象类,但是一个类能实现多个接口
  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变只能是public static final类型的
  • 抽象类中的方法可以有方法体,就能实现方法的具体功能,但是接口中的方法不行

4.当类实现接口的时候,来要实现接口中所有的方法,否则,类必须声明为抽象的类

5.一个接口能继承另一个接口,接口的继承使用extends关键字,自接口继承父接口

10.注意事项

  • 被继承的类称为超类,派生类称为子类
  • 包名所有字母小写
    • com.runoob
  • 类名每个单词首写字母大写,其他小写
    • toString()
  • 变量和方法:第一个字母小写,从第二个单词开始首字母大写
    • meditPassWord
  • 常量:所有字母大写,每个单词之间用 _ 连接
    • GAME_COLOR="RED"

11.局部变量、实例变量、类变量

类变量:独立于方法之外的变量,用static修饰
成员变量:独立于方法之外的变量,不过没有static修饰
局部变量:类的方法中的变量

1.局部变量

  • 声明在方法、构造方法或者语句块中
  • 在方法、构造方法、与巨快被执行的时候创建,当执行完成后,变量将会被销毁
  • 访问修饰符不能用于局部变量
  • 局部变量值在声明他的方法、构造方法、语句块中可见
  • 局部变量是在栈上进行分配的
  • 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用【⚠️必须初始化】

【补充】

  • 成员变量在堆内,局部变量在栈内
  • 访问修饰符
    • public
    • private
    • default
    • protected

2.成员变量--实例变量--没有被static修饰的变量

  • 声明在一个类中,但在方法、构造方法、语句块之外
  • 当一个对象被实例化后,每个实例变量的值就跟着确定了
  • 实例变量在对象创建的时候创建,在对象被销毁的时候销毁
  • 实例变量的值应该至少被一个方法、构造方法、语句块引用,是的外部能够通过这些方法获取实例变量信息
  • 实例变量可以声明在使用前或者使用后
  • 访问修饰符可以修饰实例变量
  • 实例变量对于类中的方法、构造方法、语句块是可见的。
    • 一般情况下,应该把实例变量设为私有
    • 通过访问修饰符可以使实例变量对子类可见
  • 实例变量具有默认值
    • int - 0 ; bool - false ; 引用类型变量 - null
    • 变量的值可以在声明时指定,也可以在构造方法中指定
  • 实例变量可以直接通过变量名访问。

3.类变量-静态变量-static

  • 类中以static关键字声明,但必须在方法、构造方法、语句块之外
  • 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝
  • 静态变量在程序开始时创建,在程序结束时销毁
  • 默认直通实例变量相似。

【补充】--final与static

  • final -- 常数
    • final修饰的属性跟具体对象有关,在运行期初始化的final属性,不同对象可以有不同的值
    • final修饰的方法表示该方法在子类中不能被重写,final修饰的类表示该类不能被不能被继承
    • final初始化后不能被改变,初始化的过程可以在编译期(类加载的时候)、运行期
  • static -- 静态
    • static初始化后仍可以改变
    • 用static修饰的代码表示静态代码块,当Java虚拟机(JVM)加载类的时候就会调用这个方法
    • static修饰的属性所有对象都只有一个值
    • static强调 它们 只有一个
    • static修饰的属性、方法、代码段跟该类的具体对象无关,不创建对象也能调用static的属性、方法、代码段
    • static与 this/super 势不两立,因为 this/super与具体对象有关
    • static不可修饰局部变量

12.break,continue,return

continue只是在一次循环中不继续向下进行,继续i++;而break是直接结束了本次剩下的全部i++,直接进入外部循环的j++中,而return是直接跳出了全全部不的循环

13.Java修饰符

private

public class logger{
	privite String secret;
	public String getSecret(){
		return this.secret;
	}
	public void setSecret(String secret){
		this.secret=secret;
	}
}
  • 因为logger类中的secret为私有变量,所以其他的类不能直接得到和设置该变量的值

获得 和 改变 私有变量的方法

定义的两个public方法:

  • getSecret()--返回secret的值
  • setSecret(String secret)--设置secret的值

【补充】

  • 基类就是父类,Object类是所有类的父类,父类继承父类,继承并重写父类的方法和非私有变量成员

父类中声明为private的方法,不能够被继承

14.拷贝

static关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝

局部变量(类方法中的变量)是不能被声明为static变量的

15.将底部按钮均分位置

android:layout_weight="1"

16.src与background

  • background--分割线view设置颜色
  • src--图片的背景

17.设置点击底部按钮文字变色

在drawable中,重新编写 selector的XML文件

18.FragmrntUtil

public class FragmentUtil {

    /**
     * 添加Fragment
     */
    public static void addFragment(BaseActivity context, int viewId, Fragment fragment, @Nullable String tag) {
        context.getSupportFragmentManager()
                .beginTransaction()
                .add(viewId, fragment, tag)
                .commit();

    }

    /**
     * 替换Fragment
     */
    public static void replaceFragment(BaseActivity context, int viewId, Fragment fragment, @Nullable String tag) {
        context.getSupportFragmentManager()
                .beginTransaction()
                .replace(viewId, fragment, tag)
                .commit();
    }

    /**
     * 隐藏Fragment
     */
    public static void hideFragment(BaseActivity context, Fragment fragment) {
        context.getSupportFragmentManager()
                .beginTransaction()
                .hide(fragment)
                .commit();
    }

    /**
     * 展示Fragment
     */
    public static void showFragment(BaseActivity context, Fragment fragment) {
        context.getSupportFragmentManager()
                .beginTransaction()
                .show(fragment)
                .commit();
    }

}
  • 添加Fragment
  • 替换Fragment
  • 隐藏Fragment
  • 展示Fragment

每次点击底部按钮的时候,需要先将全部的Fragment进行隐藏

   /**
     * 隐藏所有fragment
     */
    private void hideAllFragment() {

        if (mHomeFragment != null) {
            FragmentUtil.hideFragment(this, mHomeFragment);
        }
        if (mMessageFragment != null) {
            FragmentUtil.hideFragment(this, mMessageFragment);
        }
        if (mMineFragment != null) {
            FragmentUtil.hideFragment(this, mMineFragment);
        }
    }

19.给背景设置透明度--#XXXXXXe5

android:background="#1F9DD5e5"

20.底部按钮被覆盖事件

原因分析:Relativelayout布局中,需要添加一条重要的属性--above

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/frame_content"
        android:layout_above="@id/view_divider"
        >

    </FrameLayout>

    <View
        android:id="@+id/view_divider"
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:layout_above="@id/ly_bottom_menu"
        android:background="@color/colorPrimary"
        />

由于不是Linealayout,没有vertical的orientation,所以需要自己手动排布局,利用above等属性

21.报错--空指针异常!判空!判空!判空!

一定需要有if-else 的判空操作

@OnClick(R.id.ly_menu_home)
    public void onLyMenuHomeClicked() {
        changeHomeMenuStatus();
        hideAllFragment();
        if(mHomeFragment==null){
            mHomeFragment=new HomeFragment();
            FragmentUtil.addFragment(this,R.id.frame_content,mHomeFragment,null);
        }
        else{
            FragmentUtil.showFragment(this,mHomeFragment);
        }

    }

22.FrameLayout与Fragment

23.align相对布局问题

  • android:layout_alignLeft="@id/xxx"
    • 将控件的左边缘和给定ID控件的左边缘对齐
  • android:layout_alignTop="@id/xxx"
    • 将控件的上边缘和给定ID控件的上边缘对齐
  • android:layout_below="@id/xxx"
    • 将控件置于给定ID控件之下
  • android:layout_toRightOf="@id/xxx"
    • android:layout_toRightOf="@id/xxx"

24.ViewFlipper

25.Fragment中获取上下文Context一般用getActivity

应该将HomeFragment.this替换为getActivity()

getContext和getActivityhe和MainActivity.this和this

  • this--表示当前对象,一般而言,在哪个类中调用,就是指向该对象
  • MainActivity.this--表示MainActivity对象,一般用在内部类中指示外面的this,如果在内部类中直接用this,指示的是内部类本身。
  • getContext()--这是View类中提供的方法,在继承了View的类中才可以调用,反悔的时候当前View运行在那个Activity的Context中
  • getActivity()--获得Fragment所依附的Activity对象
    • 但需要注意:这个方法当Fragment生命周期结束并销毁时getActivity()返回的是null,所以在使用时要注意判断null或者捕获空指针异常。

Activity继承Context

26.Bind自动生成Flipper的时候,需要提前将项目了中的文件名更改

报错报错还是报错:

原因是:xml文件中还没有更改过,所以自动生成的还是ViewFlipper

由于我们自己写了自定义的FlipperPage,需要在xml的文件中使用它

于是我们更改为这样:

回到HomeFragment文件中对layout进行generate,就自动Bind了

27.联合主键

先排前面再排后面

28.20180326旁听安卓课--详情见笔记

29.不同类-重写,同一类-重载

子类继承父类就叫做新的一类,就叫做不同类

30.纠正:setXXX 是重载的体现

多态的三大特性:重载、重写、接口

面向对象的三大特性:继承、多态、封装

31.两个startActivity并不是报错,更不是空指针异常,这是错误的❌

两个startActivity最多就是,点击一次性进入新的Activity,回退的时候需要点击两次后退按钮而已

32.私有变量的获取

除了get方法,还可以缓存到本地,用的时候取出来就行了

33.接口与abstract类

  • 抽象类中的方法都是abstract的,但abstract类中的方法可以多种多样
  • 实现接口要实现类中的所有方法,但是abstract中的方法不需要全部实现

34.@Override--ctrl+O 万能啊

35.Error:关于ActionBar的问题--already has an action bar

借鉴:http://www.cnblogs.com/hh9601/p/6404728.html

java.lang.IllegalStateException: 
This Activity already has an action bar supplied by the window decor. Do not request Window.
FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme t

问题原因:当在activity中调用了setSupportActionBar(toolbar);

回到我的项目了文件中发现,这里确实出现了两个Bar同时存在的情形

回到AndroidManifest.xml 对应的Activity标签的android:theme中

进一步,到style中深究

于是我们换成NoActionBar

回看xml文件--成功

ok 我很喜欢

36.Toolbar取代ActionBar

借鉴网址:https://blog.csdn.net/zwlove5280/article/details/52771998

关键几个步骤:

1.在 Activity 中,用 Toolbar 取代 ActionBar(demo中将这一步封装在了BaseToolbarActivity中)

2.具体使用方法

37.Fork-Github

有一个叫做Joe的程序猿写了一个游戏程序,而你可能要去改进它。并且Joe将他的代码放在了GitHub仓库上。下面是你要做的事情:

https://linux.cn/article-4292-1-rss.html

38.SwipeRefreshLayout

https://github.com/PingerOne/SwipeRefreshDemo

【注意】

  • 在这个布局里面只能包含一个子控件,而且是可以滑动的(因为要达到刷新的目的),如:RecycleView、ListView
  • 主要方法👇

39.太机智了--BaseModel一个,利用重载,实现多个范型T都可以调用

40.Android Device Monitor--查看布局

41. .show很重要,不然Toast无限显现

在fragment中使用Toast.makeText()

 Toast.makeText(getActivity(),"此功能暂时无法使用",Toast.LENGTH_SHORT).show();

42.abstract

无法实现一个抽象类,但是可以实例化一个抽象类的子类

43.如果一个抽象类没有字段,所有方法全部都是抽象方法,就可以把抽象类改写为接口

抽象类什么都可以做,为什么还要接口呢

一个类可以实现多个接口,但是只能继承一个类

44.内部类--在一个类中的类

1.成员内部类

class heaijia{....}

👆 heaijia 这就是名字 !!有名字的类

2.静态内部类

3.局部内部类

4.匿名内部类--special--crazy

今天,我遇到了 OnClickListener()居然是以匿名内部类的形式实现的,我惊了

45.Error:ArrayAdapter requires the resource ID to be a TextView

参考:https://blog.csdn.net/zsr0526/article/details/53224064

解决办法: 将R.layout.XXX这个布局文件XXX的根节点改成TextView

根结点

46.Error :Fragment获取上下文报错

Fragment不是上下文类,所以不能直接采用this,而是利用getActivity().getApplicationContext()

借鉴:https://stackoverflow.com/questions/35816602/argument-this-doesn%C2%B4t-work-required-android-content-context

47. Error:Adapter adapter

经我测试发现,将RecyclerView换成ListView就没有报错了,具体的原因还不知道是为什么

48.Error:点击button就闪退,ListView无法显示,并且在logcat中没有明显的蓝色报错信息

layout文件中的包含关系出了问题,导致recyclerView无法显示

49.ListView

借鉴:https://www.cnblogs.com/chenyuwei/p/4581700.html

50.请见下回分解,我是何艾葭,为自己代言