【Android】各种小知识点,不间断更新

  • 提高应用启动速度splash页面瞬间响应
    App启动时闪屏页的白屏或者黑屏现象(取决于你所选取的Theme),无论怎么优化Application和启动页的onCreate都无法消除,毕竟解析界面是需要一定时间的,此时可以通过自定义启动页面的windowBackground来解决这个问题。代码如下:
<style name="AppSplash" parent="android:Theme">    
    <item name="android:windowBackground">启动页的背景图片</item>  
    <item name="android:windowNoTitle">true</item>    
</style>


  • TextView实现跑马灯效果
    普通textView需要设置四个属性

    1. android:singleLine=”true”
    2. android:ellipsize=”marquee”
    3. android:focusable=”true”
    4. android:focusableInTouchMode=”true”
    <TextView
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:textSize="24sp"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:text="这些条件必备的情况下,控件必须获得焦点才能实现跑马灯效果" />

    ListView中的textView

    1. 存在焦点的问题 所以需要额外在布局中添加一行代码

      android:marqueeRepeatLimit="marquee_forever"
    2. 并在adapter中初始化view的时候添加代码

      textView.setSelected(true);
  • TaskAffinity singleTask allowTaskReparenting组合使用 这几个属性在manifest中指定

    TaskAffinity 用于指定activity所运行的栈的名字 默认为包名
    allowTaskReparenting 允许activity的task重新指定
    TaskAffinity和singleTask配合使用时 该activity会运行在TaskAffinity指定的栈内
    TaskAffinity和allowTaskReparenting配合使用时 情况比较复杂 举例说明

    例如应用B中的一个activity指定了上述两个属性 此时A启动了应用B的该activity 此时该activity运行在应用A的栈内
    此时启动应用B 系统发现该activity应该运行的栈已经存在了 那么此时就会将该activity从应用A的栈中转移到应用B的栈中
    此时你会发现一个神奇的现象 就是应用B并没有显示他的MAinActivity 而是显示的是我们刚才在应用A中启动的activity

  • Activity中的moveTaskToBack(boolean nonRoot)

    • 正常状态下我们按下返回键 会将当前Activity销毁
      而如果我们不想销毁这个activity 而是想保持其状态的话 可以调用上述方法
    • moveTadkToBack() 在activity中调用该方法可以将activity退到后台 注意并不是finish 而是类似于最小化的状态 此时我们的activity只会执行onPause onStop方法 而不会执行onDestory方法 由于是后台状态 只要我们的进程不被杀死 下次这个activity启动的时候不会执行onCreate方法 只有第一次启动的时候才会调用onCreate方法
    • moveTaskToBack()方法中的参数指的是:
      nonRoot=true –> 仅当activity为task中的根activity时有效
      nonRoot=false –>任何时候都有效
  • view.performClick();
    调用该方法 如果这个view设置了点击事件的话 相当于调用了view的点击事件

  • fragment.setUserVisibleHint(boolean)
    一般该方法配合transaction.hide()方法同时使用 用于fragment的lazyload 该方法是通知系统该fragment的UI是否是可见的
    参考资料—–Fragment的setUserVisibleHint方法实现懒加载

  • layoutAnimation
    LayoutAnimation作用于ViewGroup,为ViewGroup指定一个动画,当他的子元素出场的时候都会附带该动画效果,常用于ListView中。使用方法如下:

    1. 定义LayoutAnimation

      //  res/anim/anim_layout.xml
      <layoutAnimation
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:delay="0.5"
          android:animationOrder="normal"
          android:animation="@anim/anim_item"/>
      

      上述属性的含义如下:

      • android:delay

        表示子元素开始动画的延迟时间,假设我们在动画中定义总时间为100ms,那么0.5表示第一个子元素延迟50ms进入,第二个延迟100ms进入,以此类推。

      • android: animationOrder

        表示子元素动画的顺序,有三个选项:normal、reverse、random,normal表示按顺序进入,reverse表示倒叙进入,random表示随即进入。

      • android:animation

        为子元素指定入场动画。

    2. 定义子元素的动画

      // res/anim/anim_item.xml
      <?xml version="1.0" encoding="utf-8"?>
      <set xmlms:android="http://schemas.android.com/apk/res/android"
          android:duration="300"
          android:interpolator="@android:anim/accelerate_interpolator"
          android:shareInterpolator="true">
      
          <alpha
              android:fromAlpha="0.0"
              android:toAlpha="1.0"/>
      
          <translate
              android:fromXDelta="500"
              android:toXDelta="0"/>
      
      </set>
      
    3. 为ViewGroup指定android:layoutAnimation属性:

      在xml布局中:androidlayoutAnimation=”@anim/anim_layout”
      或者在代码中:

      ListView listView = findViewById(R.id.listview);
      Animation animation = AnimationUtils.loadAnimation(this,R.anim.anim_layout);
      LayoutAnimationController controller = new LayoutAnimationController(animation);
      controller.setDelay(0.5f);
      controller.setOrder(LayoutAnimationController.ORDER_NOMAL);
      listView.setLayoutAnimation(controller);
  • 使用View动画中需要注意的问题,View动画是对View的影像做出的改变,因此有时候会出现动画完成之后View无法隐藏的现象,即setVisibility(View.GONE)失效了,这个时候只需要调用view.clearAnimation()清除View动画,即可解决这个问题。

  • 从3.0开始,属性动画的单击事件触发位置为移动之后的位置,但是View动画的触发位置仍然在原位置,所以,应当尽量使用属性动画来替代View动画。

  • recycleView.notify方法

    notifyItemChanged(int position),position数据发生了改变,那调用这个方法,就会回调对应position的onBindViewHolder()方法了,当然,因为ViewHolder是复用的,所以如果position在当前屏幕以外,也就不会回调了,因为没有意义,下次position滚动会当前屏幕以内的时候同样会调用onBindViewHolder()方法刷新数据了。其他的方法也是同样的道理。

    public final void notifyItemRangeChanged(int positionStart, int itemCount),顾名思义,可以刷新从positionStart开始itemCount数量的item了(这里的刷新指回调onBindViewHolder()方法)。

    public final void notifyItemInserted(int position),这个方法是在第position位置被插入了一条数据的时候可以使用这个方法刷新,注意这个方法调用后会有插入的动画,这个动画可以使用默认的,也可以自己定义。

    public final void notifyItemMoved(int fromPosition, int toPosition),这个方法是从fromPosition移动到toPosition为止的时候可以使用这个方法刷新

    public final void notifyItemRangeInserted(int positionStart, int itemCount),显然是批量添加。

    public final void notifyItemRemoved(int position),第position个被删除的时候刷新,同样会有动画。

    public final void notifyItemRangeRemoved(int positionStart, int itemCount),批量删除。

  • 在viewgroup中对一个view进行重复的添加和移除的时候,移除view时需使用如下代码:

    new Handler().post(new Runnable() {
        public void run() {
           parent.removeView(decoration);
        }
    });

    否则会报错,

    java.lang.NullPointerException: Attempt to read from field ‘int android.view.View.mViewFlags’ on a null object reference
  • so 包问题

    1. java.lang.UnsatisfiedLinkError dalvik.system.PathClassLoader[DexPathList[[zip file “/data/app/ * /base.apk”],nativeLibraryDirectories=[/data/app/ * /lib/arm, /vendor/lib, /system/lib]]] couldn’t find ” *.so”
      发生问题的手机对应的平台目录下边没有放入so包 导致系统不能正确加载

    2. dlopen failed: “/data/app/ * -1/lib/arm/ *.so” has unexpected e_machine: 3
      发生问题的手机对应的平台目录下边so包放置错误,例如x86目录下放置的是arm平台的包,当各平台so包文件名一致时需要多注意

  • recycleview中item设置matchparent无效
    解决方案:在adapter中修改:
    View view = View.inflate(parent.getContext(), R.layout.item_fra_main2, null);
    View view = mInflater.from(mContext).inflate(R.layout.item_fra_main2, parent, false);
    初始化view 的时候从第一种改为第二种方式即可。此时item的属性会跟着parent的属性走。

  • 模拟虚拟按键
    4.0之前

    
        private void sendKeyEvent(int keyCode) {    
            int eventCode = keyCode;    
            long now = SystemClock.uptimeMillis();    
            try {    
                KeyEvent down = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, eventCode, 0);    
                KeyEvent up = new KeyEvent(now, now, KeyEvent.ACTION_UP, eventCode, 0);    
                (IWindowManager.Stub    
                    .asInterface(ServiceManager.getService("window")))    
                    .injectInputEventNoWait(down);    
                (IWindowManager.Stub    
                    .asInterface(ServiceManager.getService("window")))    
                    .injectInputEventNoWait(up);    
            } catch (RemoteException e) {    
                Log.i(TAG, "DeadOjbectException");    
            }    
        } 

    4.0之后,在子线程中执行如下代码,可以模拟返回键

    public static void simulateKey(final int KeyCode) {  
    
     new Thread () {    
    
            public void run () {    
    
                try {    
    
                     Instrumentation inst=new Instrumentation();    
    
                     inst.sendKeyDownUpSync(KeyCode);  
    
                } catch(Exception e) {    
    
                    Log.e("Exception when sendKeyDownUpSync", e.toString());    
    
                }    
    
            }    
    
        }.start();    
    
    }  
    
  • 代码对文件进行重命名

    File from =new File(path) ;
    File to=new File(path) ;
    from.renameTo(to) ; 重命名sd卡文件的
    //to为重命名之后的文件
    return to;

  • substring(int beginIndex, int endIndex)

    使用该函数截取字符串的时候,如果需要截到字符串的最后一位,那么第二个参数填写的是string.length(),而不是string.length()-1,因为查看函数源码会发现,函数最终调用的是native方法fastSubstring,而第二个参数的作用是用来和第一个参数相减使用的。
    这里写图片描述

  • Mac配置adb环境变量

    1. 启动终端Terminal
    2. 输入 cd ~
    3. 输入 echo $HOME
    4. 创建.bash_profile, 可使用 vi .bash_profile (如果已存在,则自动编辑;如不存在,则自动新建)
    5. 输入 export PATH=${PATH}: <1> : <2>(其中红字为必须输入,<1> <2>之间用分号相隔,为Android SDK下的 tools 目录路径,为Android SDK下的 platform-tools 目录路径<使用pwd可以直接显示路径全称>)
    6. 保存该文件。
    7. 输入 source .bash_profile 更新刚配置的环境变量。
  • Android studio Wifi调试小工具
    源码地址:https://github.com/pedrovgs/AndroidWiFiADB
    在Android studio中打开Preferences/Settings->Plugins->Browse Repositories
    搜索Android WiFi ADB 安装重启即可 首次连接需要先通过数据线连接 并且电脑和手机处于同一无线网络中 点击插件小图标连接 成功之后即可进行无线真机调试了

  • 忽略方法数限制
    在build.gradle中添加如下代码,设置dexOptions的,不做方法数限制的检查,这样做的缺点是apk无法再低版本的设备上运行。
    这里写图片描述

  • git初次提交报错,push rejected,pull也失败

    Git Pull Failed,fatal: refusing to merge unrelated histories 

    可以尝试在version control中右键rebase on 进行合并。

  • 某些手机上边直接使用getDrawable会报错NoSuchMethod 使用getResources.getDrawable()可以解决该问题

  • 重启应用

    private void restartApplication() {  
       final Intent intent =
        getPackageManager().getLaunchIntentForPackage(getPackageName());  
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
        startActivity(intent);  
    } 
  • 使用adb命令对设备进行截图操作 并回传到电脑上
    adb shell /system/bin/screencap -p /sdcard/screenshot.png
    adb pull /sdcard/screenshot.png /Users/macmini/Downloads/screenshot.png
  • 权限
void checkPermissions() {  
       if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_CONTACTS)!= PackageManager.PERMISSION_GRANTED) {  
           if (!ActivityCompat.shouldShowRequestPermissionRationale
               (this,Manifest.permission.READ_CONTACTS)) {  
               //第一次全新进入时,shouldShowRequestPermissionRationale方法将返回false,这里将会执行。  
               //请求权限时如果点了拒绝但是没勾选不再提醒,shouldShowRequestPermissionRationale方法将返回true,这里将不执行。  
                //点了拒绝且勾选了不再提醒,再次进入时,shouldShowRequestPermissionRationale方法也将返回false,并且权限请求将无任何响应,然后可以在下面方法中做些处理,提示用户打开权限。  
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CONTACTS},1);  
            } else {  
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CONTACTS},1);  
            }  
        }  
    } 
  • Intent清空堆栈内所有的activity
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
  • activity不在堆栈中保留历史记录
    在activity的xml中设置 android:noHistory="true" 当该activity不可见时 自动销毁 并且不在堆栈中保留历史记录 也就是从下一个activity不能返回该activity
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值