移动开发

Android9.0网络兼容和依赖适配问题

客观来说,9.0兼容好像问题不是很大,很多的APP一点问题都没有,但是有些比较旧的APP就问题比较多了,下面简单写一下解决方法,本文纯属笔记,方便以后查看。 网络问题: 问题一 应对9.0 版本的网络明暗流量问题 设置一下 application (清单文件里面) 问题二 引用httpclient的报错 java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/commons/logging/LogFactory; Caused by: java.lang.ClassNotFoundException: Didn’t find class “org.apache.commons.logging.LogFactory” on path: DexPathList[[zip file “/data/app/com.inno.nestlesuper- oPFXtK6GZQsOCWb8lvmj2g==/base.apk”],nativeLibraryDirectories= [/data/app/com.inno.nestlesuper-oPFXtK6GZQsOCWb8lvmj2g==/lib/arm, /data/app/com.inno.nestlesuper-oPFXtK6GZQsOCWb8lvmj2g==/base.apk!/lib/armeabi, /system/lib, /vendor/lib]] 主要问题是 9.0版本谷歌不支持这两个网络包了需要自己导进去支持来规避兼容问题。 api files('libs/httpclient-4.3.6.jar') api files('libs/httpcore-4.3.2.jar') 然后 解决方法如下: 下载导入一个commons-logging的jar包 api files('libs/commons-logging-1.2.jar') 自此网络问题解决。 当然使用jar毕竟麻烦,时不时更新就需要改动,在此用新的方法: 在AndroidManifest.xml下的节点加入以下相关依赖(如果项目继续使用Apache的httpclient),这是因为httpclient在Android6.0就已经被废弃了,如果不想大变动我们可以将这个库强制依赖进来,避免报错。 同时在app目录下build.gradle的android节点加入httpclient依赖: useLibrary 'org.apache.http.legacy' Android9.0官方要求中,禁止传输接收没加密的数据,也就是说对网络数据传输这一块做了限制,我们需要在AndroidManifest.xml中的节点内加入网络安全配置: 其中network_security_config.xml在xml目录如下: 依赖问题 我们升级SDK编译版本和目标版本为28时,我们需要改动相应的依赖版本: implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support:support-v4:28.0.0' 冲突Program type already present 下面是一个项目build.gradle中的依赖,我们简单做一下分类 网络相关 okhttp retrofit http-legacy 常用类库 rxpermission(权限监测) leakcanary(内存泄漏)

WWDC2019 ——iOS13适配(持续更新)

第一、Web Content适配 https://developer.apple.com/videos/play/wwdc2019/511/ https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme 问题展示 先看两张图: 如上图所示,如果h5未适配dark模式,则在dark模式下原来的页面内容展示就就存在问题。 适配方法 这里主要介绍基于CSS样式的修改来适配web内容 首先,一定要声明当前支持的color-scheme有两种样式,这一句很重要,用东北话说就是“必须的” :root { color-scheme: light dark; } 适配的策略就是为两种color-scheme设置不同的颜色样式。 1、文本适配 如图一,它的CSS描述为 body { color: black; } h1 { color: #333; } .header { background-color: #593a78; color: white; } 这里相关的颜色样式都是写死的,所以dark模式下才会出现图二的情况。现在我们来看如何适配下面这段代码: h1 { color: #333; } .header { background-color: #593a78; color: white; } 然后可用如下方式改造: :root { color-scheme: light dark; --post-title-color: #333; --header-bg-color: #593a78; --header-txt-color: white; } h1 { color: var(--post-title-color); } .header { background-color: var(--header-bg-color); color: var(--header-txt-color); } 这里所做的工作实际上是抽象了颜色的值的setter和getter,即不同模式下的值统一定义,然后使用时通过var()去自动获取。

Flutter资源管理

资源管理 Flutter应用程序可以包含代码和 assets(有时称为资源)。assets是会打包到程序安装包中的,可在运行时访问。常见类型的assets包括静态数据(例如JSON文件)、配置文件、图标和图片(JPEG,WebP,GIF,动画WebP / GIF,PNG,BMP和WBMP)等。 指定 assets 和包管理一样,Flutter也使用pubspec.yaml文件来管理应用程序所需的资源。举一个例子: flutter: assets: - assets/my_icon.png - assets/background.png assets指定应包含在应用程序中的文件。 每个asset都通过相对于pubspec.yaml文件所在位置的显式路径进行标识。asset的声明顺序是无关紧要的。asset的实际目录可以是任意文件夹(在本示例中是assets)。 在构建期间,Flutter将asset放置到称为 asset bundle 的特殊存档中,应用程序可以在运行时读取它们(但不能修改)。 Asset 变体(variant) 构建过程支持asset变体的概念:不同版本的asset可能会显示在不同的上下文中。 在pubspec.yaml的assets部分中指定asset路径时,构建过程中,会在相邻子目录中查找具有相同名称的任何文件。这些文件随后会与指定的asset一起被包含在asset bundle中。 例如,如果应用程序目录中有以下文件: …/pubspec.yaml …/graphics/my_icon.png …/graphics/background.png …/graphics/dark/background.png …etc. 然后pubspec.yaml文件中只需包含: flutter: assets: - graphics/background.png 那么这两个graphics/background.png和graphics/dark/background.png 都将包含在您的asset bundle中。前者被认为是main asset (主资源),后者被认为是一种变体(variant)。 在选择匹配当前设备分辨率的图片时,Flutter会使用到asset变体(见下文),将来,Flutter可能会将这种机制扩展到本地化、阅读提示等方面。 加载 assets 您的应用可以通过AssetBundle对象访问其asset 。有两种主要方法允许从Asset bundle中加载字符串或图片(二进制)文件。 加载文本assets 通过rootBundle 对象加载:每个Flutter应用程序都有一个rootBundle对象, 通过它可以轻松访问主资源包,直接使用package:flutter/services.dart中全局静态的rootBundle对象来加载asset即可。 通过 DefaultAssetBundle 加载:建议使用 DefaultAssetBundle 来获取当前BuildContext的AssetBundle。 这种方法不是使用应用程序构建的默认asset bundle,而是使父级widget在运行时动态替换的不同的AssetBundle,这对于本地化或测试场景很有用。 通常,可以使用DefaultAssetBundle.of()在应用运行时来间接加载asset(例如JSON文件),而在widget上下文之外,或其它AssetBundle句柄不可用时,可以使用rootBundle直接加载这些asset,例如: import 'dart:async' show Future; import 'package:flutter/services.dart' show rootBundle; Future loadAsset() async { return await rootBundle.

echart相关操作xAxis,yAxis,series,grid,(包括x轴样式,y轴样式,折现样式,网格样式,折现阴影,折线上方显示数据,x轴文字倾斜)

样式截图大概如下: 1. x,y轴相关操作:xAxis,yAxis (1) x,y轴的颜色: axisLine: { lineStyle: { color: '#2898e5', }, }, (2) x,y轴文字颜色: axisLabel: { show: true, textStyle: { color: '#019bf8' } } (3)x,y轴刻度颜色: axisTick: { lineStyle: { color: '#2898e5' } } (4) x,y轴坐标文字太长显示不全:,倾斜rotate axisLabel: { show: true, interval: 0, rotate: 20 }, (5)x ,y 轴网格线的颜色: splitLine: { show: true, lineStyle: { color: ['rgb(1,155,246,0.3)'], //网格线 width: 1, } }, 2. 折现 的样式 (1) 折现的平滑度series: symbol: 'circle', //实心点 symbolSize: 6, //实心点的大小 smooth: true, //折现平滑 (2)折现的颜色:

Activity页面变暗并且不可点击只能返回的问题

场景:一个Activity请求网络,当出现网络问题请求出错时,会弹出一个Dialog提示。但是,在结果返回之前就跳到了另一个Activity,使得之前那个Activity处于后台,此时如果回到之前的Activity会出现页面变暗,而且任何地方不能点击的现象。这是由于Activity处于后台,弹Dialog遇到问题没有弹出来,但是页面已经变暗了,并抢占了焦点,使得底部的控件看得见但不可点击。给人的感觉就是App死机了,只有点返回键才能激活页面。查了半天,只遇到一个知己遇到和我一样的问题,并提出来了。有人给了一些方案。如下:https://www.iteye.com/problems/77129 我的场景不太一样,Dialog弹出没有那么重要,极端情况下Dialog可以不弹出,只要页面不变暗并且不可点击。所以我的思路是:只要Activity不是可见的,就不在当前Activity上调用弹出Dialog的操作。具体操作如下: 在我的网络请求框架MyGernericCallback上作如下判断: //只有当Activity处于前台时,才在当前Activity上弹Dialog if (IsActivityForegroundUtil.isForeground((Activity) mContext)) { try { dialog.show(); } catch (Exception e) { e.printStackTrace(); } } IsActvityForegroundUtil.java import android.app.Activity; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.text.TextUtils; import java.util.List; public class IsActivityForegroundUtil { /** * 判断某个界面是否在前台 * * @param activity 要判断的Activity * @return 是否在前台显示 */ public static boolean isForeground(Activity activity) { return isForeground(activity, activity.getClass().getName()); } /** * 判断某个界面是否在前台 * * @param context Context * @param className 界面的类名 * @return 是否在前台显示 */ public static boolean isForeground(Context context, String className) { if (context == null || TextUtils.

cocos creator 图片黑边, 灰边问题的解决

软件环境:cocos creator 2.0 cocos creator 中的图片或多或少有些黑边或灰边的问题,一般是在透明图片的边缘。 图片来自网络 问题是由于纹理缩放边缘插值计算导致的,cocos2d—x中精灵的blend源默认应该是one,但是cocos creator不是。 Cocos2d-x 中的设置更加智能,默认对图片进行 WebGL 预乘,如果发现贴图是已经预乘过的,那么 Sprite 就使用 ONE 作为 blend src,否则使用 SRC_ALPHA。这里带来的问题是,贴图切换,用户手动修改 Blend function 的冲突,cocos2d-x 在切换贴图的时候,会自动根据贴图的预乘属性重新设置 Blend function,而不管用户是否手动修改过,这里就有潜在的 bug 可能。 解决方案一: 利用打包工具 TexturePacker 将资源打包成图集,打包过程中设置成预乘: 图片来自网络 解决方案二: 在cocos creator编辑器的sprite 设置为图集里边的图,然后Blend/SrcBlendFactor设置为one : 图片来自网络 方案三:通过代码修改sprite的混合模式: node.getComponent(cc.Sprite).srcBlendFactor = cc.macro.BlendFactor.ONE; 【互动教程列表,真正的手把手教学模式,点击或扫码下载】

设置Android系统永不休眠灭屏(Android 8.0源码修改)

设置Android系统永不休眠灭屏(Android 8.0源码修改) From: zhoujinjian Date: Thu, 14 Feb 2019 17:24:00 +0800 Subject: [PATCH] feat(Policy) : 保持屏幕不灭屏feature实现 Description: Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.SCREEN_STAY_ON_ANYWAY, 1); 说明:1保持常亮,0规定时间灭屏,系统初始化默认保持常亮 Project:android/platform/frameworks/base --- diff --git a/api/current.txt b/api/current.txt index 2836067..806665c 100755 --- a/api/current.txt +++ b/api/current.txt @@ -35044,6 +35044,7 @@ field public static final java.lang.String RADIO_CELL = "cell"; field public static final java.lang.String RADIO_NFC = "nfc"; field public static final java.lang.String RADIO_WIFI = "wifi"; + field public static final java.lang.String SCREEN_STAY_ON_ANYWAY = "

Android 获取圆角图标bitmap黑色背景问题解决

一、问题场景 在做社会化分享到微博时要展示应用图标,一般获取图标作为bitmap的方法如下: Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher); 我用该代码分享出去一个圆角的图标,但是圆角部分展示为黑色,并且无法去除。 二、解决步骤 private Bitmap getBitmapByBg(Bitmap bitmap, int color){ Bitmap newBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_4444); Canvas canvas = new Canvas(newBitmap); canvas.drawColor(color); Paint paint = new Paint(); canvas.drawBitmap(bitmap, 0, 0, paint); return newBitmap; } 搞定!

解决设置沉浸式时华为手机底部导航栏兼容性问题

在设置沉浸式时,华为手机底部导航栏会覆盖app的真实内容,提供以下解决方案: 判断是否有导航栏并且获取高度,然后给window的content设置padding public static int getNavigationBarHeight(Context context) { boolean hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey(); boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); if (!hasMenuKey && !hasBackKey) { Resources resources = context.getResources(); int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");//获取NavigationBar的高度 int height = resources.getDimensionPixelSize(resourceId); return height; } else { return 0; } } 判断是否存在导航栏,并且返回高度,然后在activity的基类里设置 getWindow().getDecorView().findViewById(android.R.id.content).setPadding(0, 0, 0, getNavigationBarHeight(this)); 这样就能完美适应了,沉浸式改怎么做就这么做

android studio 的 sync、make、clean、rebuild、build APK

一、sync idea 官网说明 功能是: Synchronizing Changes in Gradle Project and IntelliJ IDEA Project 即同步 gradle 项目和 idea 项目 点击 as 的 help/Show Log in Finder(windows 可能略有不同) 点击 sync 后,查看 log: 2018-10-13 12:04:31,930 [e-1024-b01] INFO - e.project.sync.GradleSyncState - Started sync with Gradle for project 'JitpackTest'. 2018-10-13 12:04:43,183 [d thread 3] INFO - ild.invoker.GradleBuildInvoker - About to execute Gradle tasks: [:app:generateDebugSources] 可看出,同步后,执行了 :app:generateDebugSources task。 二、make 查看 as 的 log(部分): 2018-10-13 13:49:51,668 [e-1024-b01] INFO - ild.