在android studio3 问题汇总

在android studio3 下面,使用multiDexEnabled true造成导出的包缺少内容(support-v4) 如图:图一添加使用multiDexEnabled true,图二没有添加multiDexEnabled 有没有其他理想的解决方法,希望大家评论给我,谢谢 2.在build.gradle中忽略重复的引用,使用exclude(如果想在一个包忽略多个添加多行) 格式:implementation(‘引用的库’){ exclude group:’包名’,module:’模块名称(通常是包名后面和版本直接的内容)’ } 如果是 implementation project需要写成这种格式(把project扩在小括号中) implementation(project(‘……’)){ …同上 } 注意:可以单独使用group和module(推荐都写上) 例如: implementation(‘com.google.android:flexbox:0.2.3’) { exclude group: ‘com.android.support’, module: ‘appcompat-v7’ } 3. implementation 和compile 区别 (compile是被废弃了) 在AS3.0默认推荐使用implementation,如果依赖有问题使用api代替implementation, 更多参考:(自备梯子)https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html 或者:(不用梯子)https://developer.android.google.cn/studio/build/gradle-plugin-3-0-0-migration.html 4.所有项目使用指定库配置(更多请参考:http://www.jianshu.com/p/429733dbbc34) 例如: allprojects { repositories { jcenter() google() } configurations.all((Closure) { resolutionStrategy { force ‘com.android.support:support-v4:26.0.2’ // your version of support library } }) } 希望大家评论交流!!! 转自:http://www.zdltech.com/blogphp/archives/1335.html aapt2的作用说明 开启了aapt2后,资源的增量编译会加速编译速度,但是有些场景aapt2并不是很合适,因此必要的情况下,建议关闭aapt2,比如jenkins上构建时,我们并不需要增量编译,因此可以关闭,可以通过gradle参数达到关闭的效果,命令如下 1 gradle assembleRelease -Pandroid.enableAapt2=false 简单总结了几种不适合使用aapt2的场景 插件化和热修复中,需要使用public.xml的场景 构建过程,需要动态增删改资源的场景,如删除一部分线上不应该出现的资源

2017年11月3日 · 1 分钟 · 天边的星星

Android Studio3.0更新之路(遇坑必入)

序言:作为这个世界上走在最前沿的生物“猿”,怎么能对新事物一无所知呢,10月26日,随着Android 8.1 Oreo的预览版发布,Android Studio3.0正式版也发布了,作为Android开发的猿们我们应该早就知道谷歌在今年5月的开发者大会上就说了要支持Kotlin语言,所以这次更新一个比较大的点就在于支持Kotlin语言了,下面就跟着LZ的脚步来探索一下AS3.0吧 相信很多人很早就体验过谷歌爸爸放出来的体验版本了,虽然说正式版已经出了,但是很多人也不敢轻易贸然的更新,因为怕会掉进坑里出不来(真是一只胆小的猿,鉴定完毕) 安装 如果你从Android Studio内部点击更新的话,会跳转到Android的官网,没有梯子的同学可以去这个网站下载更新: ![Android Studio3.0更新之路(遇坑必入)](http://upload-images.jianshu.io/upload_images/490111-251c2b749c023786.jpg?imageMogr2/auto-orient/strip) Android Studio3.0正式版 安装过程中遇到的问题 1、Gradle Sync failed: `<span class="typ">Gradle</span><span class="pln"> sync failed</span><span class="pun">:</span> <span class="typ">Cause</span><span class="pun">:</span><span class="pln"> com</span><span class="pun">.</span><span class="pln">android</span><span class="pun">.</span><span class="pln">build</span><span class="pun">.</span><span class="pln">gradle</span><span class="pun">.</span><span class="pln">api</span><span class="pun">.</span><span class="typ">BaseVariant</span><span class="pun">.</span><span class="pln">getOutputs</span><span class="pun">()</span><span class="typ">Ljava</span><span class="pun">/</span><span class="pln">util</span><span class="pun">/</span><span class="typ">List</span><span class="pun">;</span> <span class="typ">Consult</span><span class="pln"> IDE log </span><span class="kwd">for</span><span class="pln"> more details </span><span class="pun">(</span><span class="typ">Help</span> <span class="pun">|</span> <span class="typ">Show</span> <span class="typ">Log</span><span class="pun">)</span> <span class="pun">(</span><span class="lit">8s</span> <span class="lit">123ms</span><span class="pun">)</span> ` 其实一开始不是这个错,最开始是一个redownload的一个错,后来LZ把2.3版本的给删了,缓存给清除了,然后就变成这个错了。既然有错,那就解决呗,顺手百度了一个,下面看看stackoverflow的解决方案 ...

2017年10月29日 · 2 分钟 · 天边的星星

Android USB转串口通信开发基本流程

好久没有写文章了,年前公司新开了一个项目,是和usb转串口通信相关的,需求是用安卓平板通过usb转接后与好几个外设进行通信,一直忙到最近,才慢慢闲下来,趁着这个周末不忙,记录下usb转串口通信开发的基本流程。 我们开发使用的是usb主机模式,即:安卓平板作为主机,usb外设作为从机进行数据通信。整个开发流程可以总结为以下几点: 1.发现设备 usbList = usbManager.getDeviceList();1 2 1 2 " data-snippet-id="ext.1d1481e9c3517ce217b699b6673dd389" data-snippet-saved="false" data-codota-status="done">`<span class="typ">UsbManager</span><span class="pln"> usbManager </span><span class="pun">=</span> <span class="pun">(</span><span class="typ">UsbManager</span><span class="pun">)</span><span class="pln"> context</span><span class="pun">.</span><span class="pln">getSystemService</span><span class="pun">(</span><span class="typ">Context</span><span class="pun">.</span><span class="pln">USB_SERVICE</span><span class="pun">);</span> <span class="typ">Map</span><span class="pun"><</span><span class="typ">String</span><span class="pun">,</span> <span class="typ">UsbDevice</span><span class="pun">></span><span class="pln"> usbList </span><span class="pun">=</span><span class="pln"> usbManager</span><span class="pun">.</span><span class="pln">getDeviceList</span><span class="pun">();</span>` 通过UsbManager这个系统提供的类,我们可以枚举出当前连接的所有usb设备,我们主要需要的是UsbDevice对象,关于UsbDevice这个类,官方是这样注释的: `<span class="typ">This</span> <span class="kwd">class</span><span class="pln"> represents a USB device attached to the android device </span><span class="kwd">with</span><span class="pln"> the android device acting </span><span class="kwd">as</span><span class="pln"> the USB host</span><span class="pun">.</span>` 是的,这个类就代表了android所连接的usb设备。 ...

2017年10月19日 · 3 分钟 · 天边的星星

Android布局中的空格和占一个汉字宽度的空格的实现

在Android布局中进行使用到空格,以便实现文字的对齐。那么在android中如何表示一个空格呢? 注:下面的#160,#8201等等皆需要加上&方可实现效果 空格:#160; 窄空格:#8201; 一个汉字宽度的空格:#160;#160;#8201;,用两个空格(#160;#160;)占一个汉字的宽度时,两个空格比一个汉字略窄,三个空格(#160;#160;#160;)比一个汉字略宽 在实际使用中需要灵活使用#160;和#8201;的组合。 android:text=”真实姓名:” android:text=”身 份 证:” android:text=”姓 ‒名:” android:text=”身份证:” #8194;半个中文字更准确点, #8195;一个中文字但用起来会比中文字宽一点点。 所以中文对齐还是建议使用#8194;, 而#160; #8201;在不同机型有不同表现。 TextView实现首行缩进的方法: 在string资源文件中,在文字的前面加入”\u3000\u3000”即可实现首行缩进 在Java代码中,使用setText(“\u3000\u3000”+xxxxx); \u3000是全角空格的16进制Unicode编码。 \xa0代表 转自:http://blog.csdn.net/u014651216/article/details/52411113

2017年10月17日 · 1 分钟 · 天边的星星

android textview 自动换行 整齐排版

一、问题在哪里? textview显示长文字时会进行自动折行,如果遇到一些特殊情况,自动折行会杯具成这个样子: 上述特殊情况包括: 1)全角/半角符号混排(一般是数字、字母、汉字混排) 2)全角/半角标点符号出现在行首时,该标点符号会连同其前一个字符跳到下一行 3)英文单词不能被折成两行 4)…… 二、怎么搞? 通常有两类解决方案: 1)修改文本内容,将所有符号全角化、在标点符号前面加空格等等…… 2)保持文本内容不变,在合适的位置将文本手动分成多行 本文采用第二种方案,更加通用,也最大限度的保留了原文本。 三、开始干活 3.1 “在合适的位置将文本手动分成多行”需要知道textview的实际宽度、字体大小等信息,框架如下: ![复制代码](http://common.cnblogs.com/images/copycode.gif) 1 public class TestCActivity extends Activity { 2 private TextView mText; 3 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 8 setContentView(R.layout.testc); 9 10 mText = (TextView)findViewById(R.id.txt); 11 mText.setText("本文地址http://www.cnblogs.com/goagent/p/5159125.html本文地址啊本文。地址。啊http://www.cnblogs.com/goagent/p/5159125.html"); 12 mText.getViewTreeObserver().addOnGlobalLayoutListener(new OnTvGlobalLayoutListener()); 13 } 14 15 private class OnTvGlobalLayoutListener implements OnGlobalLayoutListener { 16 @Override 17 public void onGlobalLayout() { 18 mText.getViewTreeObserver().removeOnGlobalLayoutListener(this); 19 final String newText = autoSplitText(mText); 20 if (!TextUtils.isEmpty(newText)) { 21 mText.setText(newText); 22 } 23 } 24 } 25 26 private String autoSplitText(final TextView tv) { 27 final String rawText = tv.getText().toString(); 28 final Paint tvPaint = tv.getPaint(); 29 final int tvWidth = tv.getWidth() - tv.getPaddingLeft() - tv.getPaddingRight(); 30 31 //autoSplitText begin.... 32 String newText = rawText; 33 //autoSplitText end.... 34 35 return newText; 36 } 37 } ![复制代码](http://common.cnblogs.com/images/copycode.gif) 3.2 实现自动分割文本,简单来说就是用textview的paint逐字符测量,如果发现当前行绘制不下了,就手动加入一个换行符: ...

2017年10月16日 · 6 分钟 · 天边的星星

Android动态获取权限

前几天在网上找了找Android动态获取权限的文章和视频,自己整理了一下。几天看一位大神说真正的程序员是有着分享精神的,我这个刚刚入行的小菜鸟,也想把自己整理的东西分享给大家。 本文参考了A_si的Permission——郭霖认为最优的运行时权限方案和郭霖大神的CSDN视屏 在这之前,我们需要知道什么是权限? 权限是一种安全机制。Android权限主要用于限制应用程序内部某些具有限制性特性的功能使用以及应用程序之间的组件访问。 比如网络权限 " data-snippet-id="ext.1ecd4ff36f58d5c42638b9d887b68988" data-snippet-saved="false" data-codota-status="done">&lt;user-permission android:name="android.permission.INTERNET"/&gt;当我们的程序需要访问网络的时候,必须添加这个权限,不添加则无法访问网络。 这里还需要注意的是:在Android6.0之前,我们只需要在AndroidManifest.xml文件中直接添加权限即可,但是在Android6.0之后,我们只在AndroidManifest.xml文件中配置是不够的,还需要在Java代码中进行动态获取权限。当然这里不是所有的权限都需要动态获取,只需要获取危险权限就可以了。(毕竟Android权限100多种,要是每个都需要获取,那不累死开发人员啦) Android中的危险权限分为9组24种 ![](http://upload-images.jianshu.io/upload_images/3780051-92dda32c577e32cb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 1454742-2c2196fd438a4ed3.png 我们只需要在用这些权限的时候,才需要去动态申请,除这些之外的权限,我们只需要在AndroidManifest.xml文件种写上即可,动态申请的权限同样需要在AndroidManifest.xml文件中写。而且每一组种的权限只要有一个授权了,其他的也会自动授权 下面这张图是我们的build.gradle文件中的版本信息 ![](http://upload-images.jianshu.io/upload_images/3780051-e00a73adfc0a922a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) Image.png 1、targetSdkVersion版本号如果<= 21时,不需要动态处理权限 。但是有时候我们的应用程序会打不开。 2、如果是之前的老版本升级上来的,系统会默认开启之前所有的权限,比如之前的targetSdkVersion是21,后来升级之后变成了25,这个时候系统会自动授权。一定要记住是升级变成的25,否则还是需要授权。 Tips: 为什么SD卡读写权限是危险权限,能不能不申请权限但又能使用SD卡呢? (1)把SD权限设置为危险权限,是为了防止应用随便在用户的手机上些东西,如果不加防范,用户的SD卡就会有很多乱七八糟的东西。 (2)用户可以不申请权限而使用SD卡,但是只能使用系统提供的默认的路径。 我们可以使用Android系统提供的SDK目录。路径是Android\data\程序包名。这个目录是程序可以不需要经过 用户授权就可以直接使用,甚至不需要添加WRITE_EXTERNAL_STORAGE这个权限。 这个目录会在程序删除时也会直接删除。 如何访问这个目录呢? File file = getExternalCacheDir(); String s = file.getPath; 这个方法得到的是cache的路径,但是一般的垃圾清理软件都可以把这里面的数据清理掉 File[] files = getExternalCacheDirs(); 这个得到的是一个文件数组,要求Api最小19 如果我们不想垃圾清理软件把我们缓存的数据清理掉,则可以放在file文件下 getExternalFilesDir(“”); 这个表示所有的操作都是放在file目录下进行的 getExternalFilesDir(“mm”); 这个表示会在file目录下在见一个mm目录,然后所有的操作都会放在这个目录下。 下面我们来看如何动态获取权限!!! 先看最简单的,动态获取一个权限 比如现在要动态获取一个打电话的权限。。 首先需要在AndroidManifest.xml文件中写上这个权限 " data-snippet-id="ext.f281d8d8d9cfe2d283d570842a2b4c1e" data-snippet-saved="false" data-codota-status="done">&lt;user-permission android:name="android.premission.CALL_PHONE"/&gt; 然后在Java代码进行动态获取 请求授权的代码 ` &lt;span class="hljs-comment">/** * 请求授权 */&lt;/span> &lt;span class="hljs-function">&lt;span class="hljs-keyword">private&lt;/span> &lt;span class="hljs-keyword">void&lt;/span> &lt;span class="hljs-title">requestPermission&lt;/span>&lt;span class="hljs-params">()&lt;/span>&lt;/span>{ &lt;span class="hljs-keyword">if&lt;/span> (ContextCompat.checkSelfPermission(&lt;span class="hljs-keyword">this&lt;/span>, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED){ &lt;span class="hljs-comment">//表示未授权时&lt;/span> &lt;span class="hljs-comment">//进行授权&lt;/span> ActivityCompat.requestPermissions(&lt;span class="hljs-keyword">this&lt;/span>,&lt;span class="hljs-keyword">new&lt;/span> String[]{Manifest.permission.CALL_PHONE},&lt;span class="hljs-number">1&lt;/span>); }&lt;span class="hljs-keyword">else&lt;/span>{ &lt;span class="hljs-comment">//调用打电话的方法&lt;/span> makeCall(); } }` 请求之后,我们需要重写onRequestPermissionsResult这个方法 ...

2017年10月11日 · 8 分钟 · 天边的星星

Android apk反编译及重新打包流程

### 一、反编译代码 **1、**反编译java代码首先需要下载**dex2jar**这个工具,下载地址:[https://sourceforge.net/projects/dex2jar/files/](https://sourceforge.net/projects/dex2jar/files/) 目前最新版是2.0, 下载完后并解压缩。 2、将要反编译的apk文件重命名为zip格式并解压缩,注意其中的classes.dex文件,它存放了全部的java代码,将classes.dex文件拷贝到dex2jar解压后的根目录下。 **3、**打开cmd,进入dex2jar解压后的根目录,执行命令: ** d2j-dex2jar classes.dex 如下图: ![](http://upload-images.jianshu.io/upload_images/1633070-6fc5febd3f11a9ef.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> dex2jar </div> 命令执行完后在对应目录下会生成<strong>classes-dex2jar.jar**文件 ![](http://upload-images.jianshu.io/upload_images/1633070-ba7fc87bb47cc64e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> jar文件 </div> **4、**要查看java代码,还需要下载**jd-gui**这个工具,下载地址:[http://jd.benow.ca/](http://jd.benow.ca/),目前最新版是1.4.0,下载完后解压缩,并用**jd-gui.exe**打开上边反编译出来的jar文件: ![](http://upload-images.jianshu.io/upload_images/1633070-3bb77b39750f7562.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> java code </div> 到此,已经顺利的反编译出了java代码 那资源文件呢,再回头看一下刚才apk文件对应的解压缩文件,所有的xml文件都是乱码,例如AndroidManifest.xml: ![](http://upload-images.jianshu.io/upload_images/1633070-2e019b033641d4d3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> AndroidManifest.xml </div> 当然要还原原始的资源文件还是有办法的,继续往下看。 二、反编译资源 **1、**要反编译apk中的资源文件,就需要**apktool**这个工具了,下载地址:[http://ibotpeaches.github.io/Apktool/install/](http://ibotpeaches.github.io/Apktool/install/),进入下载页面: ![](http://upload-images.jianshu.io/upload_images/1633070-6715ef0d87edee56.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> apktool download </div> 按照图中1、2两条的提示,下载**apktool.bat和apktool.jar**这两个文件,目前最新的apktool是2.1.1,并放到同一文件夹: ![](http://upload-images.jianshu.io/upload_images/1633070-e6e8d64f3519b021.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <div class="image-caption"> apktool </div> , **2、**将要反编译的apk文件放到apktool文件夹,打开cmd,进入apktool文件夹目录,执行命令: ...

2017年10月11日 · 2 分钟 · 天边的星星

SpringBoot 学习网站收藏

Spring Boot加载配置文件 https://my.oschina.net/wangyuefive/blog/704615#h3_4 问题3:如何根据线上环境和线下环境加载不同的配置?如何加载多个配置文件? 1、Profiles: Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只能在特定的环境下生效。在配置文件中,用spring.profiles.active属性来指定特定环境的配置文件。在Spring Boot中多环境配置文件名需要满足application-{profile}.properties的格式,其中{profile}对应你的环境标识,比如: application-dev.properties:开发环境 application-test.properties:测试环境 application-prod.properties:生产环境 至于哪个具体的配置文件会被加载,需要在application.properties文件中通过spring.profiles.active属性来设置,其值对应{profile}值。例如: application.properties配置:spring.profiles.active = dev即指定application-dev.properties会被加载。 2、通过启动参数指定运行环境。 通过命令行启动: ` java -jar xxxxx.jar &lt;span class="hljs-comment">--spring.profiles.active=prod。&lt;/span>` 上述指定为prod环境,则spring application会自动根据application-{profile}.properties的格式找到application-prod.properties文件加载。 3、加载多个自定义文件。 例如: ` spring.profiles.active = dev,database` 等于告诉Spring Boot加载application-dev.properties和application-database.properties文件,从而实现多个配置文件的加载。 四种读取properties文件的方式 http://www.imooc.com/article/18252 集成Mybatis http://www.imooc.com/article/15406 开启定时任务 http://www.imooc.com/article/15612 spring-boot上传文件MultiPartFile获取不到文件问题解决 http://blog.csdn.net/happy_cheng/article/details/54178392 Spring boot上传文件时MultipartFile为空问题 http://blog.csdn.net/tanga842428/article/details/72773773 spring boot默认日志配置,以及改用log4j日志配置学习使用排出多余的依赖 http://blog.csdn.net/yanweihpu/article/details/54139382 http://blog.csdn.net/loongshawn/article/details/50951329

2017年9月20日 · 1 分钟 · 天边的星星

spring-boot–使用thymeleaf模板

参考:http://blog.csdn.net/u014695188/article/details/52347318 参考:http://blog.csdn.net/u012706811/article/details/52185345 整体步骤: (1) 在pom.xml中引入thymeleaf; (2) 如何关闭thymeleaf缓存 (3) 编写模板文件.html Spring Boot默认就是使用thymeleaf模板引擎的,所以只需要在pom.xml加入依赖即可: «/span>dependency> «/span>groupId>org.springframework.boot</groupId> «/span>artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> Thymeleaf缓存在开发过程中,肯定是不行的,那么就要在开发的时候把缓存关闭,只需要在application.properties进行配置即可: [html] view plain copy ######################################################## ###THYMELEAF (ThymeleafAutoConfiguration) ######################################################## #spring.thymeleaf.prefix=classpath:/templates/ #spring.thymeleaf.suffix=.html #spring.thymeleaf.mode=HTML5 #spring.thymeleaf.encoding=UTF-8 # ;charset= is added #spring.thymeleaf.content-type=text/html # set to false for hot refresh spring.thymeleaf.cache=false 编写模板文件src/main/resouces/templates/helloHtml.html [html] view plain copy 编写访问路径(com.kfit.test.web.TemplateController): [html] view plain copy package com.kfit.test.web; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** 模板测试. @author Administrator */ @Controller publicclass TemplateController { /** ...

2017年9月19日 · 2 分钟 · 天边的星星

Android java.security.NoSuchProviderException: no such provider: Crypto

由于项目的优化改进,用到AES+RSA加密传输数据。于是,在网上摘录了网友们的AES算法,如下: **public static byte**[] encrypt(**byte**[] raw, **byte**[] clear) **throws **Exception { SecretKeySpec skeySpec = **new **SecretKeySpec(raw, **"AES"**); Cipher cipher = Cipher.getInstance(**"AES"**); cipher.init(Cipher.***ENCRYPT_MODE***, skeySpec); **byte**[] encrypted = cipher.doFinal(clear); **return **encrypted; } **public static byte**[] decrypt(**byte**[] raw, **byte**[] encrypted) **throws **Exception { SecretKeySpec skeySpec = **new **SecretKeySpec(raw, **"AES"**); Cipher cipher = Cipher.getInstance(**"AES"**); cipher.init(Cipher.***DECRYPT_MODE***, skeySpec); **byte**[] decrypted = cipher.doFinal(encrypted); **return **decrypted; } **public static byte**[] getRawKey(**byte**[] seed) **throws **Exception { KeyGenerator kgen = KeyGenerator.getInstance(**"AES"**); SecureRandom sr = SecureRandom.getInstance(**"SHA1PRNG"**, **"Crypto"**); sr.setSeed(seed); kgen.init(128, sr); SecretKey skey = kgen.generateKey(); **byte**[] raw = skey.getEncoded(); **return **raw; } 一切正常的在Android 4.3-6.1的手机上加解密,但是我用 *LGE Nexus 5X (7.1.1 API 25)*上发现在Android N上 google去掉了**Crypto **provider,意味着我们将不能继续像上面那样对数据加密填充。当然,在studio里的Logcat里会提示前往关于Android N对Crypto的解决方案: http://Android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html ...

2017年9月5日 · 2 分钟 · 天边的星星