Android开发中遇到的问题总结【一】

版权声明:本文为博主原创文章,转载请标明出处 https://blog.csdn.net/qq_30993595/article/details/81675694

PhotoView+ViewPager 发生java.lang.IllegalArgumentException: pointerIndex out of range异常

描述:当PhotoView 和 ViewPager 组合时 ,用双指进行放大时 是没有问题的,但是用双指进行缩小的时候,程序就会崩掉

原因:多次触发触摸屏事件,导致对同一个事件处理的消息过多,当第一个消息已处理完事件并销毁事件时,
由于该事件已销毁但还没来得及通知销毁第二个同样的消息,当主线程执行第二个消息时,由于获取不了该事件,
所以抛出异常。简单理解就是2个控件对同一个MotionEvent出现了冲突.

解决:自定义一个类去继承ViewPager ,然后重写Viewpager的 onInterceptTouchEvent()的方法,捕捉该异常。

/**
 * Created by cxy
 * on 2017/7/5.
 * 解决  photoview 与viewpager 组合时 图片缩放的错误 ;
 * 异常:.IllegalArgumentException: pointerIndex out of range
 */

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 (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }
        return false;
    }

}

viewpageradapter 调用notifyDataSetChanged()时不刷新页面.

原因:在getItemPosition()方法的源码中如果item的位置如果没有发生变化,则返回POSITION_UNCHANGED。
如果返回了POSITION_NONE,表示该位置的item已经不存在了。默认的实现是假设item的位置永远不会发生变化,
而返回POSITION_UNCHANGED。

解决:修改适配器的写法,覆盖getItemPosition()方法,当调用notifyDataSetChanged时,
让getItemPosition方法人为的返回POSITION_NONE,从而达到强迫viewpager重绘所有item的目的。


当使用Fragment去嵌套另外一些子Fragment的时候,我们需要去管理子Fragment,这时候需要调用ChildFragmentManager去管理这些子Fragment,由此可能产生的Exception主要是: Java.lang.IllegalStateException: No activity

描述:当第一次从一个Activity启动Fragment,然后再去启动子Fragment的时候,存在指向Activity的变量,但当退出这些Fragment之后回到Activity,然后再进入Fragment的时候,这个变量变成null

原因:Fragment在detached之后都会被reset掉,但是它并没有对ChildFragmentManager做reset,所以会造成ChildFragmentManager的状态错误

解决:我们需要在Fragment被detached的时候去重置ChildFragmentManager

@Override
  public void onDetach() {
    super.onDetach();
    try {
      Field childFragmentManager = Fragment.class
          .getDeclaredField("mChildFragmentManager");
      childFragmentManager.setAccessible(true);
      childFragmentManager.set(this, null);

    } catch (NoSuchFieldException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }

使用Write_setting权限出现java.lang.IllegalArgumentException: You cannot keep your settings in the secure settings.

在android 6.0及以后,WRITE_SETTINGS权限的保护等级已经由原来的dangerous升级为signature,
这意味着我们的APP需要用系统签名或者成为系统预装软件才能够申请此权限,并且还需要提示用户跳转到修改系统的设置界面去授予此权限,debug模式是不能申请该权限


didn’t find class on path dexpathlist

保证工程和引用库文件用同一个支持包,删除build目录,clean工程
eq:第一个activity引用android.app.activity包,第二个activity引用v7包的AppcompantActivity,这样可能就会报找不到第一个activity


AndroidStudio打包时报错The same input jar is specified twice

原因 是build.gradle文件配置了
dependencies {
compile fileTree(include: ‘*.jar’, dir: ‘libs’)
}
这里面已经添加过jar包,但是又在混淆文件proguard.cfg里面又加了句-libraryjars libs/*.jar,
将-libraryjars libs/*.jar 前面用#号注释或者直接删掉即可。

注意:sdk 通过 proguard 混淆代码时默认已经将 lib目录中的 jar 都已经添加到打包脚本中,所以不需要再次手动添加。


Activity当中的EditText的软键盘弹出问题

这个在mainfest.xml中activity下面有一个属性为windowSoftInputMode,它共有10个值可以配置,每个配置都对页面输入法弹出框影响不同

  1. stateUnspecified :即未指定状态,当没有设置android:windowSoftInputMode属性的时候,默认是这样的交互方式,系统会依据界面採取对应的软键盘的显示模式。比如当界面上仅仅有文本和button的时候,软键盘就不会自己主动弹出。由于没有输入的必要
  2. stateUnchanged:即状态不改变。就是当前界面的软键盘状态,取决于上一个界面的软键盘状态。比如当前界面键盘是隐藏的,那么跳转之后的界面,软键盘也是隐藏的;当前界面是显示的,那么跳转之后的界面,软键盘也是显示状态
  3. stateHidden:假设我们设置了这个属性,那么键盘状态一定是隐藏的,无论上个界面什么状态。也无论当前界面有没有输入的需求,反正就是不显示。因此,我们能够设置这个属性,来控制软键盘不自己主动的弹出
  4. stateAlwaysHidden:这个属性也能够让软键盘隐藏。
  5. stateVisible:能够将软键盘自动弹出来,即使在界面上没有输入框的情况下也能够强制弹出来
  6. stateAlwaysVisible:也是可以主动将软键盘弹出来,可是与stateVisible属性有小小的不同之处。举个样例,当我们给A界面设置为stateVisible属性,假设当前的界面键盘是显示的,当我们跳转到下个界面再回到当前界面的时候,键盘这个时候是隐藏的;可是假设我们设置为stateAlwaysVisible,我们跳转到下个界面再次回来的时候。软键盘是会显示出来的
  7. adjustUnspecified:设置软键盘与软件的显示内容之间的显示关系。当没有设置这个值的时候,这个选项也是默认的设置模式,第一:页面没有滚动控件的时候,当输入框会被弹出软键盘挡住的情况下,将输入框上移,以保证输入框处于用户视野范围,其它视图不变,如果不会被挡住,页面视图位置不会变动;第二:页面有滚动控件的时候,将页面整体视图上移,保证处于软键盘上方
  8. adjustResize:同上,但是有两点不同,第一:这个属性是将Activity整个界面往上移动,保证处于软键盘的上方,全部View可见;第二:会自动将软键盘弹出
  9. adjustPan:与adjustUnspecified属性类似,但是有一点不同,就是页面有滚动控件的时候,只会保证输入控件不被软键盘挡住,其它视图不保证
  10. adjustNothing:这个属性没有实际意义,软键盘弹出的时候,页面所有View不会变动

socket读取的时候报java.net.SocketException: Connection reset

这是因为
1,如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。
2,一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。
简单的说就是在连接断开后的读和写操作引起的。


socket连接的时候报java.net.ConnectException: Connection refused: connect

这是因为服务端没有启动,或者与服务端连接的端口或者ip不一致,意思就是连接不到相对应的服务端


查询服务器端口是否有数据发出

LINUX:
telnet 10.100.20.137 7780 #查看10.100.20.137服务器的7780是否有数据发出
tcpdump udp port 11011 #是否有数据走UDP协议往端口11011发
tcpdump tcp port 8888 #是否有数据走TCP协议往端口8888发

WIN方法:
winshark


端口占用情况

有时候在运行一些开发工具的时候经常会碰到端口被占用的情况,比如adb运行端口被其它流氓软件占用,解决如下

  • 可以通过 netstat -ano,列出所有端口的情况
  • 通过netstat -aon|findstr “5037” (5037是adb端口)命令查看这个端口所对应的进程PID
  • 输入tasklist|findstr “2720” 查看该pid对应进程的进程名称(2720是进程pid)
  • 输入taskkill /im sjk_daemon.exe /f 杀死进程名为sjk_daemon.exe的进程

字符串拼接

在开发中通常使用 + 号来将几个String进行拼接显示到XML中的TextView标签里,这显然是不合理的,可以使用getString方法进行更完美的实现

说到getString方法需要先说到三个约束符

  • %n$ms:n表示第几个参数;m表示间隔几个空格显示,3表示一个空格,4表示两个空格,以此类推;s表示这是一个String的约束符
  • %n$md:前面几个符号与上面类似,只有d不同,表示这是整数的约束符
  • %n$mf:因为f表明这是一个浮点型数据的约束符,所以m表示保留几位小数;.1表明保留一位小数,.2保留两位小数,以此类推,数字前面的点号不要忘了

举例:

eq1:在strings.xml中定义一个格式约束符

<resources>
    <string name="format">%1$s(%2$d/%3$d),%4$s(%5$1.1f)</string>
</resources>

可以看到这里总共是由2个String、2个整数、1个浮点数组成
接下来在代码里使用

String result = getString(R.string.format,"小明作业完成情况",8,16,"完成率",0.5);

打印出来的结果如下

小明作业完成情况(8/16),完成率(0.5)

eq2:上面的格式约束符是由纯符号组成,也可以文字加符号一起

<resources>
    <string name="age">我今年%1$d岁了,来自%2$s</string>
</resources>

这里需要使用format方法,其实你看getString源码实现,就知道最后也是调用的format方法

String age = String.format(getString(R.string.age),15,"北京");

打印结果

我今年15岁了,来自北京

eq3:如果需要文字的一部分用特殊颜色显示,可以使用html

<string name="pay"><![CDATA[<b>应付:</b> <font color=#F09B02>¥%1$.2f</font>]]></string>
<string name="seller"><![CDATA[共<font color=#f37214>%1$d</font>件,合计: <font color=#f37214>¥%2$.2f</font> 元]]> </string>
mText.setText(Html.fromHtml(String.format(getResources().getString(R.string.pay),66.66)));

这里面的应付两个字也可以用上面的例子中的约束符替代,然后在代码里可以动态显示xxx应付,这样就更加动态化了,适应性更强

猜你喜欢

转载自blog.csdn.net/qq_30993595/article/details/81675694