陋室铭


  • 首页

  • 分类

  • 归档

  • 标签
陋室铭

迁移至AndroidX

发表于 2021-12-03 | 阅读次数

引用官方文档

前提条件

执行迁移之前,请先将应用更新到最新版本。 我们建议您将项目更新为使用支持库的最终版本:版本 28.0.0。 这是因为,1.0.0 版本的 AndroidX 工件是与支持库 28.0.0 工件等效的二进制文件。

使用 Android Studio 迁移现有项目

在gradle.properties文件中新增android.useAndroidX=true和android.enableJetifier=true(使第三方库支持)

使用 Android Studio 3.2 及更高版本,您只需从菜单栏中依次选择 Refactor > Migrate to AndroidX,即可将现有项目迁移到 AndroidX。

迁移坑

  1. 库映射
    检查gradle文件中对应的旧库是否已经映射为最新的androidx库

  2. 库类映射
    检查Java文件以及xml文件中的旧的类包,是否已经映射为新的androidx包,不要遗漏。

陋室铭

树莓派相关

发表于 2020-07-05 | 阅读次数

MongoDB

1
2
sudo systemctl enable mongodb
sudo systemctl start mongodb
陋室铭

css控制文字,超出部分显示省略号

发表于 2020-06-30 | 阅读次数

单行文本溢出显示省略号

1
2
3
overflow: hidden;
text-overflow:ellipsis;
white-space:nowrap;

多行文本溢出显示省略号

1
2
3
4
5
6
overflow:hidden; 
text-overflow:ellipsis;
display: -webkit-box;//必须结合的属性 ,将对象作为弹性伸缩盒子模型显示
-webkit-box-orient: vertical;//必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式
-webkit-line-clamp: 3;//用来限制在一个块元素显示的文本的行数
overflow: hidden;

适用范围:
因使用了WebKit的CSS扩展属性,该方法适用于WebKit浏览器及移动端

陋室铭

如何居中

发表于 2020-06-15 | 阅读次数
  • 水平居中
    给div设置一个宽度,然后添加 margin:0auto 属性

    1
    2
    3
    4
    div {
    width: 200px;
    margin: 0auto;
    }
  • 水平居中,利用text-align:center实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    .container {
    background: rgba(0, 0, 0, 0.5);
    text-align: center;
    font-size: 0;
    }

    .box {
    display: inline-block;
    width: 500px;
    height: 400px;
    background-color: pink;
    }
  • 让绝对定位的div居中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    div {
    position: absolute;
    width: 300px;
    height: 300px;
    margin: auto;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-color: pink; /*方便看效果*/
    }
  • 水平垂直居中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /*确定容器的宽高宽500高300的层设置层的外边距div{*/
    position:absolute;/*绝对定位*/
    width:500px;
    height:300px;
    top:50%;
    left:50%;
    margin:-150px00-250px;/*外边距为自身宽高的一半*/
    background-color:pink;/*方便看效果*/
    }
  • 水平垂直居中二

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /*未知容器的宽高,利用`transform`属性*/
    div {
    position: absolute; /*相对定位或绝对定位均可*/
    width: 500px;
    height: 300px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: pink; /*方便看效果*/
    }
  • 水平垂直居中三

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /*利用flex布局实际使用时应考虑兼容性*/
    .container {
    display: flex;
    align-items: center; /*垂直居中*/
    justify-content: center; /*水平居中*/
    }
    .containerdiv {
    width: 100px;
    height: 100px;
    background-color: pink; /*方便看效果*/
    }
  • 水平垂直居中四

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /*利用text-align:center和vertical-align:middle属性*/
    .container {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.5);
    text-align: center;
    font-size: 0;
    white-space: nowrap;
    overflow: auto;
    }

    .container::after {
    content: "";
    display: inline-block;
    height: 100%;
    vertical-align: middle;
    }

    .box {
    display: inline-block;
    width: 500px;
    height: 400px;
    background-color: pink;
    white-space: normal;
    vertical-align: middle;
    }

解析
对于宽高固定元素

  1. 利用margin:0auto来实现元素的水平居中
  2. 利用绝对定位,设置四个方向的值都为0,并将margin设置为auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中
  3. 利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过margin负值来调整元素的中心点到页面的中心
  4. 利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过translate来调整元素的中心点到页面的中心
  5. 使用flex布局,通过align-items:center和justify-content:center设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中

注: 对于宽高不定的元素,上面的后面两种方法,可以实现元素的垂直和水平的居中

陋室铭

localStorage, sessionStorage,cookie三者的适用场景分析

发表于 2020-03-23 | 阅读次数

H5浏览器缓存技术有以下三种:localStorage,sessionStorage,cookie

  • localStorage 没有时间限制的数据存储,localStorage的生命周期是永久的,除非用户显示的再浏览器提供的UI上清除localStorage的信息,否则这些信息将永远存在。存放的数据大小一般为5MB,而且它仅再客户端中保存,不参与和服务器的通信。

  • sessionStorage 仅再当前会话下有效,即会话级存储,关闭页面或浏览器后被清除。存放的数据大小一般为5MB,而且它仅再客户端中保存,不参与和服务器的通信。

  • cookie 生命周期为只在设置cookie过期时间之前一直有效,即时窗口或浏览器关闭。存放数据大小为4K左右。有个数限制,一般不超过20个。与服务器通信,每次都会携带再HTTP投中,如果使用cookie保存过多数据会带来性能问题。

token一般使用cookie存储,可以设置过期时间

陋室铭

android8.0及9.0适配

发表于 2019-05-15 | 阅读次数

Android8.0适配

  1. 通知
    Android8.0引入了通知渠道,其允许您为要显示的每种通知类型创建用户自定义的渠道。targetSdkVersion为26的应用创建通知时必须传入channelId,否则通知将不会显示。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (manager!=null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//创建通知渠道
NotificationChannel mChannel = new NotificationChannel("channel_default", "订阅消息", NotificationManager.IMPORTANCE_DEFAULT);
manager.createNotificationChannel(mChannel);
}
NotificationCompat.Builder mBuilder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
mBuilder=
new NotificationCompat.Builder(context,"channel_default")
.setSmallIcon(R.drawable.ic_icon_niu)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_icon))
.setContentText(content);
}else{
mBuilder=
new NotificationCompat.Builder(context,null)
.setSmallIcon(R.drawable.ic_icon_niu)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_icon))
.setContentText(content);
}
if (TextUtils.isEmpty(title)) {
title = context.getResources().getString(R.string.app_name);
}
mBuilder.setContentTitle(title);
mBuilder.setDefaults(Notification.DEFAULT_ALL);
mBuilder.setAutoCancel(true);
mBuilder.setContentIntent(pendingIntent);
mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(content));
int nid = new Random().nextInt(10000000);
manager.notify(nid, mBuilder.build());
}
  1. 后台执行限制

    如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用 startService() 函数,则该函数将引发一个 IllegalStateException。

我们无法得知系统如何判断是否允许应用创建后台服务,所以我们目前只能简单 try-catch startService(),保证应用不会 crash,示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Intent intent = new Intent(getApplicationContext(), InitializeService.class);
intent.setAction(InitializeService.INITIALIZE_ACTION);
intent.putExtra(InitializeService.EXTRA_APP_INITIALIZE, appInitialize);
ServiceUtils.safeStartService(mApplication, intent);

public static void safeStartService(Context context, Intent intent) {
try {
context.startService(intent);
} catch (Throwable th) {
DebugLog.i("service", "start service: " + intent.getComponent() + "error: " + th);
ExceptionUtils.printExceptionTrace(th);
}
}

  1. 允许安装未知来源应用
    针对8.0的应用需要在AndroidManifest.xml中声明REQUEST_INSTALL_PACKAGES 权限,否则将无法进行应用内升级。
1
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
  1. 主题的Activity设置屏幕方向
    针对8.0的应用,设置了透明主题的Activity,再设置屏幕方向,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowIsTranslucent">true</item>
    </style>

    <activity
    android:name=".MainActivity"
    android:screenOrientation="portrait"
    android:theme="@style/AppTheme">
    </activity>

    将会抛出以下异常:

    1
    java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation

    即使满足上述条件,该异常也并非一定会出现,为什么这么说,看下面两种表现:

  • targetSdk=26,满足上述条件,API 26 手机没问题,API 27 手机没问题
  • targetSdk=27,满足上述条件,API 26 手机Crash,API 27 手机没问题

可知,targetSdk=26时,API26和27都没问题

  1. 桌面图标适配
    针对8.0的应用如果不适配桌面图标,则应用图标在Launcher中将会被添加白色背景
    图标适配

6.隐式广播

由于 Android 8.0 引入了新的广播接收器限制,因此您应该移除所有为隐式广播 Intent 注册的广播接收器。将它们留在原位并不会在构建时或运行时令应用失效,但当应用运行在 Android 8.0 上时它们不起任何作用。

显式广播 Intent(只有您的应用可以响应的 Intent)在 Android 8.0 上仍以相同方式工作。
这个新增限制有一些例外情况。如需查看在以 Android 8.0 为目标平台的应用中仍然有效的隐式广播的列表,请参阅隐式广播例外。

自定义的广播无法被静态注册的BroadcastReceiver收到了,一下几个解决方案:

  1. 动态注册BroadcastReceiver
    因为registerReceiver()方法只能从一个运行的进程里调用,也就是说你需要一个正在运行的Activity或者一个后台Service,这样的方法虽然可用,但是这个进程终究会被kill导致广播收不到。

  2. JobScheduler
    官方推荐使用 JobScheduler 代替原来用隐式广播实现的「当某条件达成时发生广播完成某事」的「周期性」功能,并没有广播那么灵活。

  3. 改为显示广播
    如果广播只是APP自己发自己收,那么改为显示广播是最简单的。

    1
    2
    3
    intent.action = "com.example.test.CLOSE”;
    intent.setPackage(getPackageName()); //指定包名
    context.sendBroadcast(intent);

    但是如果要发给其他 App 接收,而且不知道他们的包名的情况下,该怎么做的。
    通过pm把所有隐式注册了这个自定义广播的 App列出来,然后转成显式调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Intent intent = new Intent();    
intent.setAction("com.example.test.CLOSE");
sendImplicitBroadcast(context, intent);

private static void sendImplicitBroadcast(Context context, Intent i) {
PackageManager pm = context.getPackageManager();
List&lt;ResolveInfo&gt; matches = pm.queryBroadcastReceivers(i, 0);
for (ResolveInfo resolveInfo : matches) {
Intent intent = new Intent(i);
intent.setPackage(resolveInfo.activityInfo.applicationInfo.packageName);
intent.setAction("com.example.test.CLOSE");
context.sendBroadcast(intent);
}
}

Android9.0 适配

  1. Apache HTTP client 相关类找不到
    将 compileSdkVersion 升级到 28 之后,如果在项目中用到了 Apache HTTP client 的相关类,就会抛出找不到这些类的错误。这是因为官方已经在 Android P 的启动类加载器中将其移除,如果仍然需要使用 Apache HTTP client,可以在 Manifest 文件中加入:
    1
    <uses-library android:name="org.apache.http.legacy" android:required="false"/>

在Android6.0以上使用

1
2
3
android {
useLibrary 'org.apache.http.legacy'
}

  1. 隐私权变更
    如果您的应用需要访问设备的硬件序列号,您应改为请求 READ_PHONE_STATE 权限,然后调用 getSerial()

    1
    2
    3
    4
    5
    6
    7
    String serial;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
    serial=Build.getSerial()。
    }else{
    serial=Build.SERIAL;
    }

  2. 安全
    默认情况下启用网络传输层安全协议 (TLS)
    如果您的应用 Target 28+,则默认情况下 isCleartextTrafficPermitted() 函数返回 false。 如果您的应用需要为特定域名启用明文,您必须在应用的网络安全性配置中针对这些域名将 cleartextTrafficPermitted 显式设置为 true。

定义配置文件 res/xml/network_security_config.xml:

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">secure.example.com</domain>
</domain-config>
</network-security-config>

然后在清单文件中申明

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config"
... >
...
</application>
</manifest>

陋室铭

Linux运维

发表于 2019-04-23 | 阅读次数
  1. 仅清除页面缓存

    1
    sync; echo 1 > /proc/sys/vm/drop_caches
  2. 清除目录项和inode

    1
    sync; echo 2 > /proc/sys/vm/drop_caches
  3. 清除页面缓存,目录项和iNode

    1
    sync; echo 3 > /proc/sys/vm/drop_caches

手动清理内存缓存

1
2
3
cat /proc/sys/vm/drop_caches

echo 3 > /proc/sys/vm/drop_caches
陋室铭

springboot相关知识

发表于 2019-02-24 | 阅读次数
  1. SpringBoot优点
  • 独立运行
  • 简化配置
  • 自动配置
  • 应用监控
  • 上手容易
  1. SpringBoot 的配置文件有哪几种格式?他们有什么区别?
  • .properties

    1
    app.user.name=demo
  • .yml

    1
    2
    3
    4
    app:
    user:
    name: demo

.yml格式不支持@PropertySource注解导入配置

  1. SpringBoot的核心注解有哪些?
    启动类注解@SpringBootApplication,它是SpringBoot的核心注解,包含以下3个注解:
    @SpringBootConfiguration:组合了@Configuration注解,实现配置文件功能
    @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能:@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })

@ComponentScan:Spring组件扫描

  1. SpringBoot运行方式
  • 命令打war包放到容器中运行
  • 用maven/gradle插件运行 mvn springboot:run
  • 直接执行main方法
  1. 如何在 Spring Boot 启动的时候运行一些特定的代码
    可以通过实现接口ApplicationRunner或者CommandLineRunner,这两个接口实现方式一样,都只提供一个run方法

CommandLineRunner:启动获取命令行参数

1
2
3
public interface CommandLineRunner {
void run(String... args) throws Exception;
}

ApplicationRunner:启动获取应用启动的时候参数

1
2
3
public interface ApplicationRunner {
void run(ApplicationArguments args) throws Exception;
}

使用方式:

1
2
3
4
5
6
7
8
import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
public void run(String... args) {
// Do something...
}
}

或者
1
2
3
4
5
@Bean
public CommandLineRunner init() {
return (String... strings) -> {
};
}

  1. Springboot有哪几种读取配置的方式?
  • @PropertySource
  • @Value
  • @Environment
  • @ConfigurationProperties

读取application文件,在application.yml或properties文件中添加
info.address=usa
info.company=Spring
info.degree=high

@Value注解读取方式

1
2
3
4
5
6
7
8
9
10
11
12
13
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class InfoConfig1 {
@Value("${info.address}")
private String address;
@Value("${info.company}")
private String company;
@Value("${info.degree}")
private String degree;

...
}

@ConfigurationProperties注解读取方式

1
2
3
4
5
6
7
@Component
@ConfigurationProperties(prefix = "info")
public class InfoConfig2 {
private String address;
private String company;
private String degree;
}

读取指定文件
资源目录下建立config/db-config.properties:
db.username=root
db.password=123456

@PropertySource+@Value注解读取方式

1
2
3
4
5
6
7
8
@Component
@PropertySource(value = { "config/db-config.properties" })
public class DBConfig1 {
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
}

注意:@PropertySource不支持yml文件读取

@PropertySource+@ConfigurationProperties注解读取方式

1
2
3
4
5
6
7
@Component
@ConfigurationProperties(prefix = "db")
@PropertySource(value = { "config/db-config.properties" })
public class DBConfig2 {
private String username;
private String password;
}

Environment读取方式
以上所有加载出来的配置都可以通过Environment注入获取到

1
2
3
4
@Autowired
private Environment env;
// 获取参数
String getProperty(String key);

  1. SpringBoot配置加载顺序
  • properties文件
  • YAML文件
  • 系统环境变量
  • 命令行参数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    1、开发者工具 `Devtools` 全局配置参数;
    2、单元测试上的 `@TestPropertySource` 注解指定的参数;
    3、单元测试上的 `@SpringBootTest` 注解指定的参数;
    4、命令行指定的参数,如 `java -jar springboot.jar --name="Java技术栈"`;
    5、命令行中的 `SPRING_APPLICATION_JSONJSON` 指定参数, 如 `java -Dspring.application.json='{"name":"Java技术栈"}' -jar springboot.jar`
    6、`ServletConfig` 初始化参数;
    7、`ServletContext` 初始化参数;
    8、JNDI参数(如 `java:comp/env/spring.application.json`);
    9、Java系统参数(来源:`System.getProperties()`);
    10、操作系统环境变量参数;
    11、`RandomValuePropertySource` 随机数,仅匹配:`ramdom.*`;
    12、JAR包外面的配置文件参数(`application-{profile}.properties(YAML)`)
    13、JAR包里面的配置文件参数(`application-{profile}.properties(YAML)`)
    14、JAR包外面的配置文件参数(`application.properties(YAML)`)
    15、JAR包里面的配置文件参数(`application.properties(YAML)`)
    16、`@Configuration`配置文件上 `@PropertySource` 注解加载的参数;
    17、默认参数(通过 `SpringApplication.setDefaultProperties` 指定);
    数字小的优先级越高,即数字小的会覆盖数字大的参数值,我们来实践下,验证以上配置参数的加载顺序。
  1. 控制反转/依赖注入
    控制反转:是一种思想。由容器控制程序之间的关系,并为应用程序提供对象需要的外部资源。
    依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
    依赖注入机制减轻了组件之间的依赖关系,同时也大大提高了组件的可移植性,这意味着,组件得到重用的机会将会更多。
陋室铭

linux命令

发表于 2019-02-19 | 阅读次数

wc

可以计算文件的byte数,字数或列数

参数

  • -c或–bytes或–chars只显示bytes数

  • -l或–lines只显示行数

  • -w或–words只显示字数

1
2
wc testfile #testfile文件的统计信息
3 92 598 testfile #testfile文件的行数为3、单词数92、字节数598

删除x个文件

1
ls -t test-* |tail -n 5|xargs rm -f #删除5个以test-开头的文件,按时间从远到近的顺序

从远程服务器复制目录到本地

1
2
3
4
5
6
7
8
9
10
11
12
13
14
scp -r root@10.10.35.21:/app/env/redis/conf/ ./




scp ./service-basicdata-provider-5.0.0-SNAPSHOT.jar root@10.10.35.15:/app

scp ./service-basicdata-provider-5.0.0-SNAPSHOT.jar root@10.10.35.18:/app/service-basicdata-provider-5.0.0-SNAPSHOT


scp ./service-airline-adaptor-intl-recommend-5.0.0-SNAPSHOT.jar root@10.10.135.24:/app/service-airline-adaptor-intl-recommend-5.0.0-SNAPSHOT
/app/service-airline-adaptor-intl-recommend-5.0.0-SNAPSHOT

service-airline-adaptor-intl-recommend-5.0.0-SNAPSHOT.jar
陋室铭

maven命令package、install、deploy比较

发表于 2019-02-19 | 阅读次数

mvn clean package

依次执行clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段

mvn clean install

依次执行clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8个阶段

mvn clean deploy

依次执行clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9个阶段

区别

  • package命令完成项目编译、单元测试、打包功能

  • install命令完成项目编译、单元测试、打包功能,并把打好的可执行jar包部署到本地maven仓库

  • deploy命令完成项目编译、单元测试、打包功能,并把打好的可执行jar包部署到本地maven仓库和远程私服仓库

12…6<i class="fa fa-angle-right"></i>

53 日志
15 分类
21 标签
GitHub
© 2016 - 2024 icefire 辽ICP备16011524号-1
由 Hexo 强力驱动
主题 - NexT.Pisces