日常备忘录

[toc]

adb

  1. 权限禁止
su root 
  1. 查看xml文件
cat  data.xml
  1. 权限禁止的情况下进入包目录
run-as com.your.package  

webView图片显示不全

 webSettings.setJavaScriptEnabled(true); // 设置支持javascript脚本
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        webSettings.setBlockNetworkImage(false);

Pw在7.0或以上显示showAsDropDown有问题

public void showAsDropDown(View anchor) {
    if (Build.VERSION.SDK_INT >= 24) {// 只有7.0 的系统有这个问题
        int[] location = new int[2];
        anchor.getLocationOnScreen(location);
        int x = location[0];
        int y = location[1];
        showAtLocation(anchor, Gravity.NO_GRAVITY, 0, y + anchor.getHeight());
    } else {
        super.showAsDropDown(anchor);
    }
}

ApplicationContext以及ActivityContext区别

image.png

Retrofit 备忘录

  1. 添加拦截器添加公共头
 private fun client(): OkHttpClient {
        if (TextUtils.isEmpty(url)) {
            throw IllegalArgumentException("baseUrl can not be null")
        }
        val builder = OkHttpClient.Builder()
        builder.connectTimeout(connectTimeoutMills, TimeUnit.MILLISECONDS)
        builder.readTimeout(readTimeoutMills, TimeUnit.MILLISECONDS)
        builder.addInterceptor { chain ->
          val request = chain.request()?.newBuilder()?.addHeader("showapi_appid", NetConf.showApiAppId)
                   ?.addHeader("showapi_sign", NetConf.showApiSign)!!.build()
            chain.proceed(request)
        }
        return builder.build()
    }

2.添加拦截器添加公共参数

 private fun client(): OkHttpClient {
        if (TextUtils.isEmpty(url)) {
            throw IllegalArgumentException("baseUrl can not be null")
        }
        val builder = OkHttpClient.Builder()
        builder.connectTimeout(connectTimeoutMills, TimeUnit.MILLISECONDS)
        builder.readTimeout(readTimeoutMills, TimeUnit.MILLISECONDS)
        builder.addInterceptor { chain ->
            val httpUrl = chain.request().url().newBuilder().addQueryParameter("showapi_appid", NetConf.showApiAppId)
                    .addQueryParameter("showapi_sign", NetConf.showApiSign).build()
            val request = chain.request().newBuilder().url(httpUrl).build()
            chain.proceed(request)
        }
        return builder.build()
    }

知识点备忘录

android架构

Activity生命周期

image.png

Fragment生命周期

image.png

RxJava

image.png

部分命名规则

名称 缩写
Button btn
CheckBox cb
EditText et
FrameLayout fl
GridView gv
ImageButton ib
ImageView iv
LinearLayout ll
ListView lv
ProgressBar pb
RadioButtion rb
RecyclerView rv
RelativeLayout rl
ScrollView sv
SeekBar sb
Spinner spn
TextView tv
ToggleButton tb
VideoView vv
WebView wv

kotlin中还没理解透彻的点:

内部类的作用(好处):

讲解

image.png

线程问题:

sleep和wait的区别

  1. Sleep是Thread的方法,wait是Object类的方法
  2. Thread.sleep不会导致锁行为的改变,如果当前线程是拥有锁的,那么Thread.sleep不会让线程释放锁
  3. Thread.sleep和Object.wait都会暂停当前的线程,对于CPU资源来说,不管是哪种方式暂停的线程,都表示它暂时不再需要CPU的执行时间,但是wait需要别的线程执行notify/notifyAll才能够重新获得CPU执行时间
image.png

线程间的状态转换:

  1. 新建(new):新创建了一个线程对象。

  2. 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。

  3. 运行(running):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。

  4. 阻塞(block):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种:

  • 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。

  • 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。

  • 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

  1. 死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

总结:

  1. sleep方法调用之后,并没有释放锁。使得线程仍然可以同步控制。sleep不会让出系统资源;wait是进入线程等待池中等待,让出系统资源
  2. 调用wait方法的线程,不会自己唤醒,需要线程调用 notify / notifyAll 方法唤醒等待池中的所有线程,才会进入就绪队列中等待系统分配资源。sleep方法会自动唤醒,如果时间不到,想要唤醒,可以使用interrupt方法强行打断
  3. Thread.sleep(0) // 触发操作系统立刻重新进行一次CPU竞争。
  4. sleep可以在任何地方使用。而wait,notify,notifyAll只能在同步控制方法或者同步控制块中使用。
  5. sleep必须捕获异常,而wait,notify,notifyAll的不需要捕获异常。

数据结构

HashMap和Hashtable的区别?

  1. 两者最主要的区别在于Hashtable是线程安全,而HashMap则非线程安全
  2. HashMap可以使用null作为key,而Hashtable则不允许null作为key
  3. 两者计算hash的方法不同
    • Hashtable计算hash是直接使用key的hashcode对table数组的长度直接进行取模
    • HashMap计算hash对key的hashcode进行了二次hash,以获得更好的散列值,然后对table数组长度取摸
  4. HashMap和Hashtable的底层实现都是数组+链表结构实现

Hanler Looper Message

Looper主要作用:

  1. 与当前线程绑定,保证一个线程只会有一个Looper实例,同时一个Looper实例也只有一个MessageQueue。
  2. loop()方法,不断从MessageQueue中去取消息,交给消息的target属性的dispatchMessage去处理。

总结:

  1. 首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。
  2. Looper.loop()会让当前线程进入一个无限循环,不断从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。
  3. Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue相关联。
  4. Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。
  5. 在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法。

Context 以及ApplicationContext 使用场景

image.png

大家注意看到有一些NO上添加了一些数字,其实这些从能力上来说是YES,但是为什么说是NO呢?下面一个一个解释:

数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task。一般情况不推荐。

数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用。

数字3:在receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视)

注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。

布局优化

  1. include
  2. merge
  3. viewStub(不可以与merge同时使用,会增加绘制层数,如何取舍看具体业务)

include

  • 优点:可以引入重复内容,避免xml重复 复制黏贴
  • 缺点:可能会引入额外的布局嵌套

merge

  • 优点:是include的辅助补充,可以避免xml布局嵌套
  • 缺点:不会引用引入额外的布局嵌套

viewStub
仅在需要时才加载布局

  • 优点:仅在需要的时候才会引入布局,可以防止View.GONE导致的性能损耗
  • 缺点:比较麻烦(个人觉得)
  • 使用方法:
    • xml 中使用:
    • java代码中使用:
        <ViewStub   
            android:id="@+id/view_stub"  
            android:layout="@layout/profile_extra"  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"  
            />  
    ViewStub viewStub = (ViewStub) findViewById(R.id.view_stub);  
    if (viewStub != null) {  
        View inflatedView = viewStub.inflate();  
        editExtra1 = (EditText) inflatedView.findViewById(R.id.edit_extra1);  
        editExtra2 = (EditText) inflatedView.findViewById(R.id.edit_extra2);  
        editExtra3 = (EditText) inflatedView.findViewById(R.id.edit_extra3);  
    }  

Dalvik和ART的区别?

Dalvik与JVM的区别

  1. Dalvik指令集是基于寄存器的架构,dex字节码更适合于内存和处理器速度有限的系统。
  2. 而JVM是基于栈的。相对而言,基于寄存器的Dalvik实现虽然牺牲了一些平台无关性,但是它在代码的执行效率上要更胜一筹。
  3. Dalvik 是Android4.4及以下平台的虚拟机。Art 是在Android4.4以上平台使用的虚拟机。

ART的优点:

  1. ART 性能高于采用JIT的Dalvik
  2. 应用启动更快、运行更快、体验更流畅、触感反馈更及时
  3. 更长的电池续航能力
  4. 支持更低的硬件

ART的缺点:

  1. 字节码变为机器码之后,占用的存储空间更大
  2. 应用的安装时间会变长。

堆内存和栈内存的区别

1、应用程序所有的部分都使用堆内存,然后栈内存通过一个线程运行来使用。

2、不论对象什么时候创建,他都会存储在堆内存中,栈内存包含它的引用。栈内存只包含原始值变量好和堆中对象变量的引用。

3、存储在堆中的对象是全局可以被访问的,然而栈内存不能被其他线程所访问。

4、栈中的内存管理使用LIFO的方式完成,而堆内存的管理要更复杂了,因为它是全局被访问的。堆内存被分为,年轻一代,老一代等等,更多的细节请看,这篇文章

5、栈内存是生命周期很短的,然而堆内存的生命周期从程序的运行开始到运行结束。

6、我们可以使用-Xms和-Xmx JVM选项定义开始的大小和堆内存的最大值,我们可以使用-Xss定义栈的大小

7、当栈内存满的时候,Java抛出java.lang.StackOverFlowError异常而堆内存满的时候抛出java.lang.OutOfMemoryError: Java Heap Space错误

8、和堆内存比,栈内存要小的多,因为明确使用了内存分配规则(LIFO),和堆内存相比栈内存非常快。

HttpClient与HttpUrlConnection的区别

  • android 2.3 之前推荐用HttpClient,因为HttpUrlConnection存在较多的、莫名其妙的bug
  • android 2.3 以后推荐用HttpUrlConnection,因为更方便,更快捷。
    比如Volley
    讲解

http与https的区别:

  1. HTTP 的 URL 以 http:// 开头,而 HTTPS 的 URL 以 https:// 开头
  2. HTTP 是不安全的,而 HTTPS 是安全的
  3. HTTP 标准端口是 80 ,而 HTTPS 的标准端口是 443
  4. 在 OSI 网络模型中,HTTP 工作于应用层,而 HTTPS 工作在传输层
  5. HTTP 无需加密,而 HTTPS 对传输的数据进行加密
  6. HTTP 无需证书,而 HTTPS 需要认证证书
    讲解

Activity的启动过程:

讲得很好的一篇文章

单例模式

单例模式

日常bug

  1. ViewPager 配合PhotoView 在快递缩放的情况下会报错


    image.png

    这个时候需要自定义ViewPager

/**
 * @author Ly
 * @date 2017/12/11
 */

public class PhotoViewPager extends ViewPager {
    public PhotoViewPager(Context context) {
        super(context);
    }

    public PhotoViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        try {
            return super.onInterceptTouchEvent(ev);
        } catch (Exception e) {
            // ignore it
        }
        return false;
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        try {
            return super.onTouchEvent(ev);
        } catch (IllegalArgumentException ex) {
            // ignore it
        }
        return false;
    }
}

  1. ViewPager 图片刷新,适配器用的是FragmentStatePagerAdapter,其实应该用FragmentPagerAdapter性能更好。
/**
 * @author Ly
 * @date 2017/12/26
 */

public class BigImageAdapter extends FragmentStatePagerAdapter {

    private ArrayList<Fragment> mFragmentList;

    public BigImageAdapter(FragmentManager fm, List<String> types) {
        super(fm);
        updateData(types);
    }

    public void updateData(List<String> dataList) {
        ArrayList<Fragment> fragments = new ArrayList<>();
        for (int i = 0, size = dataList.size(); i < size; i++) {
            fragments.add(BigImageFragment.newInstance(dataList.get(i)));
        }
        setFragmentList(fragments);
    }

    private void setFragmentList(ArrayList<Fragment> fragmentList) {
        if (this.mFragmentList != null) {
            mFragmentList.clear();
        }
        this.mFragmentList = fragmentList;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return this.mFragmentList.size();
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }
}
  1. EditText 字符输入限制
    例如我的游戏区服 只能输入0-300,那么就是:
 mEtRepurchaseServed.setFilters(new InputFilter[]{new MaxNumFilter(0, 300, 2)});
/**
 * @author Ly
 *         最大输入字符限制
 *         <p>
 *         <p>
 *         eg:
 *         mEtRepurchaseServed.setFilters(new InputFilter[]{new MaxNumFilter(0, 300, 2)});
 *         mEtRepurchaseLevel.setFilters(new InputFilter[]{new MaxNumFilter(0, 65535, 2)});
 * @date 2017/12/25
 */

public class MaxNumFilter implements InputFilter {
    private final Pattern pattern;
    private final double maxNum;


    public MaxNumFilter(int min, double maxNum, int numOfDecimals) {
        pattern = Pattern.compile("^" + (min < 0 ? "-?" : "")
                + "[0-9]*\\.?[0-9]" + (numOfDecimals > 0 ? ("{0," + numOfDecimals + "}$") : "*"));
        this.maxNum = maxNum;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        if (source.equals(".")) {
            if (dstart == 0 || !(dest.charAt(dstart - 1) >= '0' && dest.charAt(dstart - 1) <= '9') || dest.charAt(0) == '0') {
                return "";
            }
        }
        if (source.equals("0") && (dest.toString()).contains(".") && dstart == 0) {
            return "";
        }

        StringBuilder builder = new StringBuilder(dest);
        builder.delete(dstart, dend);
        builder.insert(dstart, source);
        if (!pattern.matcher(builder.toString()).matches()) {
            return "";
        }

        if (!TextUtils.isEmpty(builder)) {
            double num = Double.parseDouble(builder.toString());
            if (num > maxNum) {
                return "";
            }
        }
        return source;
    }
}
  1. RecyclerView 嵌套RecyclerView 出现滑动冲突
    场景:
    RecyclerView嵌套了RecyclerView,当手指滑动子RecyclerView的时候,滑动焦点处于子RecyclerView,父RecyclerView滑动不了。
    S80125-11003805[1].jpg

这个时候,我们父RecyclerView不用做处理,子RecyclerView做如下处理:

            val discountList = arrayListOf<DiscountBean>()
            for (i in 0..1) {
                discountList.add(DiscountBean(i, i.toString(), i.toString()))
            }
            val discountAdapter = DiscountAdapter(discountList, context)
            mRlvProductDiscount?.layoutManager = LinearLayoutManager(context)
            mRlvProductDiscount?.adapter = discountAdapter
            mRlvProductDiscount?.isNestedScrollingEnabled=false

主要是这句:

 mRlvProductDiscount?.isNestedScrollingEnabled=false

禁止了该mRlvProductDiscount的滑动事件

redis 启动失败:

window下安装redis报错:
creating server tcp listening socket 127.0.0.1:6379: bind No error

的解决方案如下按顺序输入如下命令就可以连接成功


1. redis-cli.exe
2. shutdown
3. exit
4. redis-server.exe redis.windows.conf
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,479评论 25 707
  • 平顶山学院迎来了新一轮的冬天。此时此刻我不由自主的想起了十六年前的老歌“2002年的第一场雪”不知道平顶山学院的第...
    失足大学生阅读 1,397评论 0 0
  • 此时是四点半的清晨,整个世界都是一片静默。没有日间人声鼎沸的喧泄,没有车来人往的嘈杂,就像白茫茫刚下过雪的大地,天...
    挥着翅膀的懒孩阅读 176评论 0 0
  • 出生的城市,所经历的事情,不同的人生观,都在预示着你们最终会走不同的路,有不同的人生,所以呀…没什么好委屈的...
    一只迷茫的小虎阅读 223评论 0 1
  • “静心将带给你敏感,一个属于这个世界的伟大的感觉、这是我们的世界——星星是我们的,在此我们不是外来者、我们本来就属...
    老虎牙子阅读 332评论 0 0