android开发笔记汇总(二)

幸越泽
2023-12-01

有一段时间没有写博客了。一直想写,但是都被自己打败了,这里分享下这段时间遇到的bug之类的东西。

  1. adapter中的sort方法。。。 会自动生成两个基本对象,前面的是后一个对象,后面的是前一个对象,进行比较。一般是返回-1 0 1三个参数。。。负整数 0 正整数
    0表示等于 1表示大于 -1表示小于吧
  2. dialog show之前要判断activity是否已经销毁。因为网络请求是异步请求,界面销毁之后还在继续请求。就会报badtoken的异常
  3. java.lang.RuntimeException:android.os.TransactionTooLargeException: data parcel size 1037388 bytes 一般正常情况下是intent下传递bundle的大小超过1m
  4. Glide错误java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity 将mContext改为全局的application的context
  5. 异常
Unable to add window -- token android.os.BinderProxy@3d5c91ca is not valid; is your activity running
if(!((Activity) context).isFinishing()) {  
    //show dialog  
} 

`
6. android.database.sqlite.SQLiteDatabaseLockedException sqlite数据库被锁定,开始想着是因为实例化,但是log日志上面写的是在实例化完成后使用的时候出错的。。。基本不存在这种操作
7. 都知道ctrl+z是撤回,那么如何回退呢,ctrl+shift+z txt回退
8. Unknown URL content://downloads/my_downloads 偶现,可能是因为手机安全软件禁用了系统的下载,所以需要进行判断,是否被禁用,禁用就不能进行下载
9. 今天还遇到一个问题就是recycleview或者listview的item会随着滚动间距变大。。。主要是item布局的的hight属性为match_parent,然后父布局为wrap_contet自适应,会不断变大间距
10. https://tinypng.com/ 压缩图片保持不失真。
TinyPng好用的地方:
图片压缩后对视觉影响不大,但体积显著减小
可以批量压缩
压缩后文件名与原文件名相同,可以直接替换,相当赞啊,尤其是批量压缩的时候
可以反复压缩,而不用担心失真
简单有效
11.android:exported=”true” 总体来说它的主要作用是:是否支持其它应用调用当前组件。
12.奔溃捕捉机制的使用
继承UncaughtExceptionHandler 写入本地sd卡或者传递到服务器中。当然也可以使用bugly
13.java.lang.OutOfMemoryError 内存溢出
产生主要是以下原因:JVM内存过小、程序不严密,产生了过多的垃圾。
内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
代码中存在死循环或循环产生过多重复的对象实体;
使用的第三方软件中的BUG;
启动参数内存值设定的过小;
需要重点排查以下几点:
检查代码中是否有死循环或递归调用。
检查是否有大循环重复产生新对象实体。
检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
14.内存泄露
内存泄露的本质就是说长生命周期的对象持有短生命周期对象的引用,导致短生命周期的对象无法被GC。具体到你这个问题,单例模式的变量是static类型,你现在使用applicationContext是整个应用运行期间都必须要存在的,那么肯定是没有内存泄露的。但是使用activity的context就不行了,会导致activity无法被回收,造成内存泄露

15.遇到个问题就是radiogroup设置边线stroke不显示。主要是是被子项的item背景图给填充了。设置shape中的padding属性就可以了。

16.android端数据和服务器数据同步。不要每次都更新所有数据,对于频繁的数据,才有版本号控制,以增量的形式进行拉取,用时间戳进行对比。
17.二维码扫描的容错性。在光线暗的情况下或者说socket连接失败的情况下无提示
18.http请求最少要1s,正常是3-5s,所以尽量合并接口。握手花费的时间长
19.ip优选策略,返回一个ip列表进行ping优选,发送给服务端进行优选策略
20.关于socket丢消息的情况,不应该把后台返回的真实数据条数作为重连接的标准,会死循环,要使用本地实际读取到的条数为标准。
21.http请求相对于socket请求的话会比较稳定。
22.重连机制的话,多次重连,首先判断服务器是否能ping成功,成功的话重连一次
23.使用ip不用域名,省了一步域名解析,dns
24.getActivity报空指针 使用全局的context。。。主要是inflater 的contex为空,点太快的时候 context为空 application中的context 或者在activity一创建的时候创建全局变量
25.恩,了解了,Application Context只针对整个应用,而Activity 中的Context针对不同的Activity,使用时还是要当心,引用错了可能导致内存泄露
26.https://github.com/LittleFriendsGroup/AndroidSdkSourceAnalysis各种框架源码解析
27.StrictMode类是Android 2.3 (API 9)引入的一个工具类,可以用来帮助开发者发现代码中的一些不规范的问题。比如,如果你在UI线程中进行了网络或者磁盘操作,StrictMode就会通过Log(logcat )或者对话框的方式把信息提示给你,因为让你的UI线程处理这里操作会被认为是不规范的做法,可能会让你的应用变得比较卡顿。
28.instanceof Java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
29.1KB=1024个字节 1个汉字=2个字节 所以1KB=512个汉字
30. lvDailyTask.setFocusable(false);
lvTotalTask.setFocusable(false); listview适应scrollview的时候回抢占焦点,导致scrollvie滚动,要么让外部的scrollview滚动最顶端,要没就使他失去焦点
31.复制内容

ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setText(content.trim()); //将内容放入粘贴管理器
cmb.getText();//获取粘贴信息

32.Timer.schedule的3个参数。 第一个是定时任务 第二个参数是延迟秒数 第三个参数是间隔多久执行下一次
33.某次在AndroidStudio中调试程序时,发现无法指定app了,在AndroidStudio窗口的底部android选项卡顶部只出现了设备名,其右边的框框显示android no debuggable application
更新一下详细的步骤:
如果Enable ADB Integration已经打勾,那么先取消打勾
拔掉usb数据连接线Enable ADB Integration打勾
插上usb,以上,这样效果更好,之后需等待一会,可能adb会重启,之后就会发现那个框框正常显示你已启动的app
34.使用混淆,减少代码体积
删除不使用的资源
减少使用第三方库的数量,避免引入大而全的框架
压缩图片
35.一个Dialog的Theme 如果设置Android:backgroundDimEnabled为false.那弹出的对话框背景是亮的

<style name="CustomDialogStyle" parent="@android:style/Theme.Dialog">  
        <item name="android:windowBackground">@android:color/transparent</item>  
        <item name="android:windowNoTitle">true</item>  
        <item name="android:backgroundDimEnabled">true</item>  
    </style>  

36.不加限制的话会直接奔溃。低版本的api不存在改方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setNavigationBarColor(Color.TRANSPARENT);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}

37.android imageview scaletype属性

  1. SetScaleType(ImageView.ScaleType.CENTER);
    按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示

  2. SetScaleType(ImageView.ScaleType.CENTER_CROP);
    按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽) 会裁剪

  3. setScaleType(ImageView.ScaleType.CENTER_INSIDE);
    将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽

  4. setScaleType(ImageView.ScaleType.FIT_CENTER);
    把图片按比例扩大/缩小到View的宽度,居中显示

38.循环判断是否完成某个操作或者动作,记得用递归

39.glide加载图片 如果默认图片和最终加载的图片不一致就会忽大忽小
Glide有个默认的加载动画,而以前用的没有,所以试着加上了dontAnimate,禁止所有动画
.placeholder(R.drawable.icon_stub_dynamic).dontAnimate().into(iv);
可以解决这个问题!

40.ListView与EditText多行文本时的滑动冲突问题

问题描述:当EditText嵌套在ListView中且EditText设置是多行文本时,EditText本身内容本应该自带滚动效果,但当点击EditText内部滑动的时候,发现失效,这是由于外层的ListView拦截了它的子控件EditText的事件导致的。
解决方案

mEditText.setOnTouchListener(this);    
@Override    
public boolean onTouch(View v, MotionEvent event) {    
    switch (v.getId()) {    
        case R.id.edit_text:    
            v.getParent().requestDisallowInterceptTouchEvent(true);    
            switch (event.getAction()) {    
                case MotionEvent.ACTION_UP:    
                    v.getParent().requestDisallowInterceptTouchEvent(false);    
                    break;    
            }    
    }    
    return false;    
}    

思路:当发生某种触摸事件时,我们可以通过调用父控件的方法requestDisallowInterceptTouchEvent(true)来告诉父控件,我不需要你来处理这个事件,我自己可以处理。
41.getViewTreeObserver().addOnGlobalLayoutListener
我们知道在oncreate中View.getWidth和View.getHeight无法获得一个view的高度和宽度,这是因为View组件布局要在onResume回调后完成。所以现在需要使用getViewTreeObserver().addOnGlobalLayoutListener()来获得宽度或者高度。这是获得一个view的宽度和高度的方法之一

42.重启activity不带动画

 public void reload() {
    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);
    startActivity(intent);
}

43. targetSdkVersion : 22, 默认编译版本是22,默认是开着权限的。。。android编译版本使用22,默认会去请求权限,至于用户取消授权的问题,需要动态申请权限。
44.绘制整个窗口需要按顺序执行以下几个步骤:
1. 绘制背景。
2. 绘制View本身的内容。
3. 绘制子View。
4. 绘制修饰内容(例如滚动条)。

45.if(getIntent().hasExtra(“message”)) 判断intent跳转是否携带这个key

46.这个应该不是bitmap的图片大小 昨天遇到的问题是压缩图片质量传递给后台后不能压缩,先采用了压缩png的等比宽高,可以实现,但是后台的压缩图片算法会把图片按比例拉大,导致图片原图很大。。。
今天早上图片保存采用jpg的格式,压缩也用jpge的形式,上传图片只有30几k,后台返回缩略图链接7k。。。比较符合
47.大家都知道同样的尺寸,png格式的图片要比jpg图片大很多,为什么android开发对png情有独钟呢?
二者对比:
1、png有透明通道,而jpg没有
2、png是无损压缩的,而jpg是有损压缩,因此png中存储的信息会很多,体积自然就大了
3、手机对png情有独钟,会对其进行硬件加速,所以同样一张背景图,png虽然体积大,但是加载速度更快
综述:1、对于app包中的图片,我们都使用png格式的,而对于要从网络上加载的图片,考虑到流量以及下载上速度,则使用jpg格式的,因为它有较高的压缩率,体积更小。
2、对于背景图、引导页,这种大尺寸的图片,我们还是倾向于jpg格式的,虽然加载慢一些吗,但是体积小,减少了包的体积
3、Google后来发布了一种新的图片格式,WebP,它的压缩率比jpg更好,已经在慢慢普及

48.纠结。。。。ondestory 的复写方法,super的位置很重要,决定了回收顺序

//           this.recreate();
            Intent intent = getIntent();
            overridePendingTransition(0, 0);
            intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            finish();
            overridePendingTransition(0, 0);
            startActivity(intent);
 <item name="android:windowDisablePreview">true</item>
 //拒绝预加载黑屏
//去掉预启动背景
<style name="Theme.AppStartLoad" parent="android:Theme.NoTitleBar.Fullscreen">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowDisablePreview">true</item>
</style>

49.监听ViewPager滑动到最后一页时,再次拖动的方法监听

//监听ViewPager的跳转状态,当跳转到最后一页时,执行jumpToNext()方法  
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {  

            /** 
             * 在屏幕滚动过程中不断被调用 
             * @param position 
             * @param positionOffset   是当前页面滑动比例,如果页面向右翻动,这个值不断变大,最后在趋近1的情况后突变为0。如果页面向左翻动,这个值不断变小,最后变为0 
             * @param positionOffsetPixels   是当前页面滑动像素,变化情况和positionOffset一致 
             */  
            @Override  
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {  

                Log.v("AAA",isLastPage+"   "+isDragPage+"   "+positionOffsetPixels);  
                if (isLastPage && isDragPage && positionOffsetPixels == 0){   //当前页是最后一页,并且是拖动状态,并且像素偏移量为0  
                    if (canJumpPage){  
                        canJumpPage = false;  
                        JumpToNext();  
                    }  
                }  
            }

50.webview.cangoback()方法回退到上一层来判断是否返回到原生的界面

@Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
             mWebView.goBack();// 返回前一个页面
             return true;
         }
         return super.onKeyDown(keyCode, event);

51.判断是ios还是android端
webView.getSettings().setUserAgentString(“xxx/”+ AndroidUtil.getVersionName(this));这里可以定制代理连接的头部 出问题了,主要是这边设置了xxx….导致判断出错
android 设置webview的浏览器标识 User-Agent
// 修改ua使得web端正确判断
String ua = webview.getSettings().getUserAgentString();
webview.getSettings().setUserAgentString(ua+”; 自定义标记”);
52.recyclerview焦点抢占导致会乱滚动 解决方法就是在嵌套它的外面布局加获取焦点的方法 android:focusableInTouchMode=”true”
53.Android 禁止进入activity自动弹出键盘
在Manifest.xml中设定activity的属性
android:windowSoftInputMode=”stateHidden|stateUnchanged”
54.android webview加快打开速度 一般情况是阻塞图片的加载线程,加载完成webview后再去开启
一般人堆WebView的加速,都是建议先用webView.getSettings().setBlockNetworkImage(true); 将图片下载阻塞,然后在浏览器的OnPageFinished事件中设置webView.getSettings().setBlockNetworkImage(false); 通过图片的延迟载入,让网页能更快地显示。
可以看到非常显著的改善,从onPageStarted到onPageFinished只用了2秒不到的时间,这个时间主要花在HTML和CSS渲染上。从界面上来看,就是一闪而过的网页载入进度条,立即显示CSS渲染过的页面效果,然后再载入并执行JS脚本,逐块显示需要通过AJAX获取的数据。
综上,解决Android载入WebView页面慢的问题,不是Android程序员的事情,而是Web前端工程师的问题。如果您使用基于WebView的Android第三方壳工具(例如PhoneGap,可以通过这种方式改善UI界面的响应时间)。
发布这个解决方案,希望基于Web的客户端解决方案能更上一层楼,让HTML和原生APP混搭或的纯WEBAPP实现效果可以更理想,功德无量……

55.android:textCursorDrawable=”@null”设置光标在最右边的简单方法。设置setTextDirection以后小米手机出现断层。。。hint的时候,所以改了这个方法
56.Relativelayout
android:layout_above=”@id/xxx” –将控件置于给定ID控件之上
android:layout_below=”@id/xxx” –将控件置于给定ID控件之下
android:layout_toLeftOf=”@id/xxx” –将控件的右边缘和给定ID控件的左边缘对齐
android:layout_toRightOf=”@id/xxx” –将控件的左边缘和给定ID控件的右边缘对齐
android:layout_alignLeft=”@id/xxx” –将控件的左边缘和给定ID控件的左边缘对齐
android:layout_alignTop=”@id/xxx” –将控件的上边缘和给定ID控件的上边缘对齐
android:layout_alignRight=”@id/xxx” –将控件的右边缘和给定ID控件的右边缘对齐
android:layout_alignBottom=”@id/xxx” –将控件的底边缘和给定ID控件的底边缘对齐
android:layout_alignParentLeft=”true” –将控件的左边缘和父控件的左边缘对齐
android:layout_alignParentTop=”true” –将控件的上边缘和父控件的上边缘对齐
android:layout_alignParentRight=”true” –将控件的右边缘和父控件的右边缘对齐
android:layout_alignParentBottom=”true” –将控件的底边缘和父控件的底边缘对齐
android:layout_centerInParent=”true” –将控件置于父控件的中心位置
android:layout_centerHorizontal=”true” –将控件置于水平方向的中心位置
android:layout_centerVertical=”true” –将控件置于垂直方向的中心位置

57.获取20-80的随机数 m[i] = (float) (Math.random() * 80)+20f
58.以前我们要想在activity或fragment之间传递信息,我们会通过onActvityResult接收信息。但是这样有一个缺点,一个是代码量太大,重复率太高。二是有时候传递的数据需要经过几个界面的跳转。加入从A->B->C,C界面修改了某些信息,同时,想在A界面进行界面的刷新。那么通过onActvityResult的话很难操作。还有就是,加入从A->B,B传递信息给A界面。以往通过onActvityResult,我们需要在B界面关闭的时候,A界面才能拿到数据,再进行局部刷新,这样的话,A界面很可能会闪烁(数据刷新)。这样的话用户体验感就很差了
59.android去掉背景(颜色或者图片)
  view.setBackgroundResource(0);
根据文档public void setBackgroundResource (int resid)
       Since: API Level 1
Set the background to a given resource. The resource should refer to a Drawable object or 0 to remove the background.
  所以设置为o就是删除背景。

60.只有在准备结束后才能调用getDuration()方法,如果在之前调用getDuration()会出现IllegalStateException异常。

61.强转一下数据类型 1.07e啥的表示100000000


 new DecimalFormat("0.0").format(money/rate)

DecimalFormat df1 = new DecimalFormat("0.0"); 

  DecimalFormat df2 = new DecimalFormat("#.#"); 

  DecimalFormat df3 = new DecimalFormat("000.000"); 

  DecimalFormat df4 = new DecimalFormat("###.###"); 

  System.out.println(df1.format(12.34)); 

  System.out.println(df2.format(12.34)); 

  System.out.println(df3.format(12.34)); 

  System.out.println(df4.format(12.34)); 

 结果: 

 12.3 

 12.3 

 012.340 

 12.34 

StringFormatUtils.getDataSize(Long.parseLong(model.getMusicSize()),"####.##")

62.Attempt to call getDuration without a valid mediaplayer in media player on android
原因:在preparing过程中调用了getDuration方法。
You might be calling getDuration before the file is fully loaded.
63.改父类方法 而不去改子类的拓展类

63. 在java代码中设置edittext的最大字符
//最大输入18个字符
InputFilter[] filters = {new InputFilter.LengthFilter(18)};
editText.setFilters(filters);
64.计算机还原到某个时间节点导致android studio的cache无法正常使用,直接删除重新编译,发现cache的文件名字太长导致无法删除,一个比较笨的方法,添加到压缩文件,勾选压缩后删除源文件就好了。完美

65.减少apk的大小,控制图片数量,尽量不用帧动画
66.subList序列化问题
记得以前写过,这两天又遇到了,不过我记得了,写给容易忽视的人。
在切割list存储的时候,需要将结果存到tair中,很自然的想法是:originalList.subList(from, to),然后直接put到tair。以前我就这么干过,后来报了序列化异常。原因也很简单,即sublist这个List的视图,不支持序列化。
在jdk6中,List subList(int fromIndex, int toIndex)返回的是没有实现Serializable接口的java.util.RandomAccessSubList。
在其父类或者接口中都找不到Serializable这个标志。
一种可行解决方案:
List serializedList= new ArrayList();
serializedList.addAll(sublist);

67.所有的事情一定要提前做。。。比如抢票
68.忘记start 一个thread要记得start
69.替代pinyin4j的库http://p.codekk.com/detail/Android/promeG/TinyPinyin
70.使用矢量图动画 https://github.com/airbnb/lottie-android 使用过程中会报错 找不到版本build-tools 26 需要升级版本
error:
Error:Could not find com.android.support:appcompat-v7:27.0.2. Required by: project :app > com.jixxx

android 使用Lottie加载动画

 <com.airbnb.lottie.LottieAnimationView
            android:id="@+id/animation_view"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            app:lottie_fileName="music_loading.json"
            app:lottie_loop="true"
            app:lottie_autoPlay="true" />  
            //将json文件放在assets文件夹下

71.屏蔽系统自带的调节音量控件,代码如下:

@Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
            am.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, 0);
        }else if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
            am.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0);
        }
        return true;
    }

72.fragment生命周期

08-11 11:33:36.156    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint false
08-11 11:33:36.156    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ setUserVisibleHint false
08-11 11:33:36.157    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ setUserVisibleHint true
08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onAttach
08-11 11:33:36.158    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreate
08-11 11:33:36.159    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onCreateView
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onActivityCreated
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment1﹕ onResume()
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onAttach
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreate
08-11 11:33:36.160    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onCreateView
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onActivityCreated
08-11 11:33:36.161    7162-7162/com.example.yinsgo.myui V/Fragment2﹕ onResume()

73.adapter中的pos问题来防止错乱 对于popupwindow的特殊消失隐藏的需求,应该去除自身自带的外部点击消失的操作,否则容易出现逻辑错乱

74.在安装的过程中,你可能会遇到这样的错误提示:”Intel virtualization technology (vt,vt-x) is not enabled”,不用担心,这时你只需要进入BIOS界面在“configurations”中找到“Intel Virtualization Technology”将其设置成Enable即可;
一般电脑再开机界面按下delete或F2即可,不行的话按F12。在配置完之后再安装。
重新启动Android Studio,然后再次启动AVD即可。

75.图片保存到本地显示归类到其它文件夹中,为了让它不显示,添加后缀。直接去掉图片的后缀就可以了。

76.使用percentlayout应该要注意外面裹着的父布局必须设置成百分比的参数,才可以在里面设置间距。

77.’\uD83C’ 55356
所谓Emoji就是一种在Unicode位于\u1F601-\u1F64F区段的字符。这个显然超过了目前常用的UTF-8字符集的编码范围\u0000-\uFFFF。
一个表情符号 emojoi 由两个字符构成。。。所以乱码的时候会显示两个字符。。。略坑 eg \uD83C\uDF1D这样才能完整显示一个表情符号 ,遍历截取字符串,要知道每个符号所占位数。
78.Biner翻译过来是“胶水“的意思,这个翻译分形象。Binder的主要工作就是淡化了进程边界,淡化了进程间通信的过程。要是想更好的理解Binder就必须从Linux进程谈起。
79.EventBus 是一个使用“观察者模式”的、松耦合的开源框架。它使用少量的几句代码就可以实现核心类之间的通讯,帮助我们简化代码、松依赖、加速开发。
80.根据当前的设备屏幕尺寸和密度,将会寻找最匹配的资源,如果将高分辨率图片放入低密度目录,将会造成低端机加载过大图片资源,又可能造成 OOM,同时也是资源浪费,没有必要在低端机使用大图
81.IPC 即 Inter-Process Communication (进程间通信)。
82.Adblock Plus是一款能够智能屏蔽chrome浏览器中广告的插件。
83.边开发边修复?修复 Bug 时不影响正常开发?热补丁的主要优势是不会使设备当前正在运行的业务中断,即在不重启设备的情况下可以对设备当前软件版本的缺陷进行修复。——百度百科
84.使用kotlin编写代码
import kotlinx.android.synthetic.main.activity_easy.*
btn_toast.setOnClickListener { toast(“小提示:您点了一下下”) }
longToast(“长提示:您长按了一小会”)
kotlin修饰符
toInt : 转换为整型数。
toLong : 转换为长整型。
toFloat : 转换为浮点数。
toDouble : 转换为双精度数。
toChar : 转换为字符。
toString : 转换为字符串。
isNaN : 判断该变量是否为空值。
其实val和var的区别在于,前者修饰过的变量,只能在第一次声明时赋值,后续不能再赋值;而后者修饰过的变量,任何时候都允许赋值。
kotlin声明和操作数组
var int_array:IntArray = intArrayOf(1, 2, 3)
var string_array:Array = arrayOf(“How”, “Are”, “You”)
在定义的方法中 只需要用object修饰类名 那么该类名下的方法都是静态方法如果只有一部分静态方法的话
将那一部分用companion object{}包裹起来即可
85.不能直接用id的原因,你xml没有载入,会导致使用id的时候会报空指针,如果需要使用,在onCreateView return view后,在onViewCreate函数中使用Id直接调用,onViewCreate会在onCreateView后执行
分开发者博客这么写到 获取kotlin的控件,只要在代码中输入对应的Id就行了。但是,对于fragment确并不适用

这句话其它是不对的,要想直接使用控件id需要符合前置条件,就是对应的layout文件加载完毕后才可以直接使用控件id来操作,如果你在onCreateView()方法中去直接使用控件id去操作,肯定是空指针异常,因为return view还没有执行呢。

在确保onCreateView()方法执行完毕后,就可以直接使用控件id来操作。

注意到在Kotlin中,美元符号 使 属 于 特 殊 字 符 , 因 此 不 能 直 接 打 印 它 , 必 须 经 过 转 义 才 可 打 印 。 转 义 的 办 法 是 使 用 “ {‘*‘}”表达式,该表达式外层的“ ′′ ″ ” 为 转 义 声 明 , 内 层 的 “ ∗ ∗ ∗ ” 为 需 要 原 样 输 出 的 字 符 串 , 所 以 通 过 表 达 式 “ {‘$’}”即可打印一个美元符号,示例代码如下所示:

btn_dollar.setOnClickListener { tv_convert.text = “美元金额为 $ ′ $ ′ origin” }

如果只是对单个美元符号做转义,也可直接在符号$前面加个反斜杆,即“\$”,代码如下:

btn_dollar.setOnClickListener { tv_convert.text = “美元金额为 $$origin” }

精简了的代码会不会似曾相识?仿佛脱胎于C语言跟Java的三元运算符“变量名=条件语句?取值A:取值B”。可是Kotlin并不提供这个三元运算符,因为使用上述的if/else语句已经实现了同样的功能,所以多余的三元运算符就被取消了。

以往Java在使用switch/case时有个限制,就是case后面只能跟常量,不能跟变量,否则编译不通过。现在Kotlin去掉了这个限制,进行分支处理时允许引入变量判断,当然引入具体的运算表达式也是可以的。引入变量判断的演示代码如下:

总结一下,对于条件分支的处理,Kotlin实现了简单分支和多路分支,其中简单分支跟Java一样都是if/else,多路分支则由Java的switch/case升级为when/else。同时,Kotlin的条件分支允许有返回值,可算是一大改进。另外,Java的三元运算符“变量名=条件语句?取值A:取值B”,在Kotlin中取消了,对应功能改为使用if/else实现;Java的关键字instanceof也取消了,对应的类型判断功能被纳入到when/else机制中。

// 左闭右开区间,合法值包括11,但不包括66
for (i in 11 until 66) { … }
// 每次默认递增1,这里改为每次递增4
for (i in 23..89 step 4) { … }
// for循环默认递增,这里使用downTo表示递减
for (i in 50 downTo 7) { … }

!!: 表示当前对象不为空的情况下执行

?:表示当前是否对象可以为空

isNullOrEmpty : 为空指针或者字串长度为0时返回true,非空串与可空串均可调用。
isNullOrBlank : 为空指针或者字串长度为0或者全为空格时返回true,非空串与可空串均可调用。
isEmpty : 字串长度为0时返回true,只有非空串可调用。
isBlank : 字串长度为0或者全为空格时返回true,只有非空串可调用。
isNotEmpty : 字串长度大于0时返回true,只有非空串可调用。
isNotBlank : 字串长度大于0且不是全空格串时返回true,只有非空串可调用。

val strA:String = “非空”
val strB:String? = null
val strC:String? = “可空串”

对于strA,因为它是非空串,所以可直接获取length长度属性。对于strB和strC,必须进行非空判断,否则编译器会提示该行代码存在错误。

这个多出来的标记是个问号,语句“strB?.length”等价于“length_null = if (strB!=null) strB.length else null”。

所以它又引入了一个运算符“?:”,学名叫做“Elvis 操作符”,叫起来有点拗口,读者可以把它当作是Java三元运算符“变量名=条件语句?取值A:取值B”的缩写。

因为经常上一行代码就对strB赋值了,所以此时可以百分百保证strB非空,那又何必浪费口舌呢?于是Kotlin另外引入了运算符“!!”,表示甭管那么多了,前方没有地雷,弟兄们赶紧上!

1、声明对象实例时,在类型名称后面加问号,表示该对象可以为空;
2、调用对象方法时,在实例名称后面加问号,表示一旦实例为空就返回null;
3、新引入运算符“?:”,一旦实例为空就返回该运算符右边的表达式;
4、新引入运算符“!!”,通知编译器不做非空校验,运行时一旦发现实例为空就扔出异常;

1、声明对象实例时,在类型名称后面加问号,表示该对象可以为空;
2、调用对象方法时,在实例名称后面加问号,表示一旦实例为空就返回null;
3、新引入运算符“?:”,一旦实例为空就返回该运算符右边的表达式;
4、新引入运算符“!!”,通知编译器不做非空校验,运行时一旦发现实例为空就扔出异常;

设置默认值
fun getFourBigDefault(general:String, first:String=”造纸术”, second:String=”印刷术”, third:String=”火药”, fourth:String=”指南针”):String {

1、Kotlin省略了关键字public;
2、Kotlin用冒号“:”代替extends,也就是通过冒号表示继承关系;

1、二级构造函数没有函数名称,只用关键字constructor表示这是个构造函数。
2、二级构造函数需要调用主构造函数,“this(context, name)”这句代码在Java中要写在函数体内部,在Kotlin中则以冒号开头补充到输入参数后面,这意味着二级构造函数实际上是从主构造函数扩展而来,冒号表示前边属于后边的类型,犹如“var count:Int”一般。

总结一下,Kotlin给类的构造函数引进了关键字constructor,并且区分了主构造函数和二级构造函数。主构造函数的入参在类名后面声明,函数体则位于init方法中;二级构造函数从属于主构造函数,它不但由主构造函数扩展而来,而且必定先调用主构造函数的实现代码。另外,Kotlin的构造函数也支持默认参数,从而避免了冗余的构造函数定义。

1、冗余的同名属性声明;
2、冗余的同名属性赋值;
3、冗余的属性获取方法与设置方法;

然而Kotlin取消了关键字static,也就无法运用静态成员的相关手段。为了弥补这方面的功能缺陷,Kotlin引入了伴生对象的概念,可以把它理解为“影子”,伴生对象之于它所在的类,仿佛是如影随形。

Kotlin的类成员分为实例成员与静态成员两种,实例成员包括普通成员属性和成员方法,其中与入参同名的成员属性可以在构造函数中直接声明,外部必须通过类的实例才能调用实例成员。静态成员包括静态常量与静态方法,它们都在类的伴生对象中定义,外部可以通过类名直接使用静态成员。
3、Kotlin进行继承时,父类后面多了括号“()”;
86.fragment切换白屏 commit commitallowstateloss
87.解决rxjava导致的内存泄露问题
另外可以使用tinypng来降低图片大小解决
每个Android应用都有一个最大内存上限。超过这个上限,就会导致内存不足(OutOfMemory)。检查内存上限的方法:int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); Log.d(“TAG”, “Max memory is ” + maxMemory + “KB”); 通常情况下,出现OOM,是由于应用中加载了大量的图片导致。鉴于此,有以下几种方式来减小应用对内存的使用:a. 合理压缩展示图片,比如一个100x100的控件里,如果加载一个1024x768的图片,不会让图片的展示效果更好,反而会增加OOM的风险。所以,合理的对图片进行压缩非常重要。b.
压缩完图片,但是应用里包含了太多的图,这种情况依然可能出现OOM。这种情况下,考虑使用内存缓存技术。根据每一屏要展示的图片数量,以及每个图片的大
小,设定一个合理的缓存值,一般情况下不要超过1/8的最大内存值。如果图片不在显示区域,可以考虑将其进行回收,系统的垃圾回收器(GC)会认为这些内
存不在被使用,从而对图片进行GC操作。这样会大大降低OOM的风险。
88.static属性在加载时就已经分配内存,并且只分配一次,可以用于对象间共享属性。

89.final定义的变量为常量,不能被改变,方法不能被覆盖,类不能被继承。

90.会按照如下顺序加载,1、父类中的静态块、静态方法;2、子类中的静态块、静态方法;3、父类的构造块;4、父类的构造方法;5、子类的构造块;6、子类的构造方法。

91.随着Android第三库的普及,RxJava和RxAndroid(https://github.com/ReactiveX/RxAndroid)越来越被人熟知,简洁的语法,配合Java8 Lambda表达式,使代码的结构更加清晰,通过线程调度器更容易控制和切换线程,种种优点,使用它的人也越来越多。但是使用不好,很容易导致内存泄露。Rxlifecycle (https://github.com/trello/RxLifecycle)就使被用来严格控制由于发布了一个订阅后,由于没有及时取消,导致Activity/Fragment无法销毁导致的内存泄露。
92.同一个包下面不能访问private ,xutils反射加注解影响性能 ,butterknife更高效 ,会在编译的时候会生成xxxActivity_ViewBinding.class文件,增加编译的时间,增加一点包的体积,还有一个好用的插件.
93.Luban(鲁班)—Image compression with efficiency very close to WeChat Moments/可能是最接近微信朋友圈的图片压缩算法

94.开闭原则的英文全称是Open Close Principle,简称OCP
单一职责原则的英文名称是Single Responsibility Principle,简称SRP。它的定义是:就一个类而言,应该仅有一个引起它变化的原因。
面向切面编程,思想,把代码中耦合的需要判断的东西,统一提出来放到一个切面上

95.知识的诅咒 这种情况,就是《黏性》这本书所提出的“知识的诅咒”概念:当一个人知道一件事后,他就无法想象自己是不知道这件事的。

96.利用反射获取view的bitmap拷贝,这边图片特别不清晰的原因是因为界面上控件做了放大,不是对等的情况下进行对比
1.0 1.75 3.0 修改缩放比例

Bitmap bitmap=null;
        Class cls = view.getClass();
        while (!cls.getName().equals("android.view.View")){
            cls = cls.getSuperclass();
        }
        try {
            Method method = cls.getDeclaredMethod("createSnapshot", new Class[]{Bitmap.Config.class, int.class, boolean.class});
            method.setAccessible(true);
             bitmap = (Bitmap) method.invoke(view, Bitmap.Config.ARGB_8888, Color.TRANSPARENT, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;

97.如何计算Bitmap占用的内存?
还记得之前我曾言之凿凿的说:不考虑压缩,只是加载一张Bitmap,那么它占用的内存 = width * height * 一个像素所占的内存。
现在想来实在惭愧:说法也对,但是不全对,没有说明场景,同时也忽略了一个影响项:Density。
98.xx值被刷,由于点击过快的问题,导致跳转多个页面,执行了多次方法。需要在前端规避,判断多次点击的时间间隔

99.通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。

100.许多程序漏洞都基于此—-final只能保证引用永远指向固定对象,不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改,一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final,意图使得它“永远不变”。其实那是徒劳的。
101.Android开发的朋友,遇到很多这样的情况,随着功能的增加,方法数增多,就会出现所谓的64k方法数问题。
Android APK文件本质上是一个压缩文件,它包含的classes.dex文件是Dalvik字节码文件,这个dex文件中存放的就是编译后的Java代码。Dalvik可执行文件规范限制了单个.dex文件最多引用的方法数是65536个。

102.这里加0.5f的巧用目的是:被整除后还能四舍五入

103.vcl播放器 支持倍数 自定义快捷键ctrl+↑ 就是加速播放

总结:通过这次胡乱的一次分享,我懂得了要用markdown及时记录每天遇到的问题,及时总结,计划要细致到天,后续还有一些近期认为值得分享的东西可以写一写,突然觉得知识累计着就会变旧,变得一文不值,看书,看视频都要做减法,培养自己的执行力,从每天晨跑开始,这周一定写一些比较有质量的博客出来。

 类似资料: