全部流媒体Android后端前端版本控制公告服务器产品经理设计师猿科技
最新 最热 官方 加精

蓝皮鼠 | 4天前 | vueAndroid

Vue.js 实现与Android互调

三步搞定:Vue.js调用Android原生操作 这篇文章主要介绍了三步搞定:Vue.js调用Android原生操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 第一步: Android对Js的接口,新建AndroidInterfaceForJs.js js import android.content.Context; import android.os.Build; import android.os.Handler; import android.os.Looper; import android.support.annotation.RequiresApi; import android.util.Log; import android.webkit.JavascriptInterface; import android.webkit.ValueCallback; import android.widget.Toast; import com.just.agentweb.AgentWeb; import com.yidumedical.ui.activity.PAWebActivity; / Created by shiby on 2018/1/24. / public class AndroidInterfaceForJS { private Handler deliver = new Handler(Looper.getMainLooper()); private AgentWeb agent; private Context context; public AndroidInterfaceForJS(AgentWeb agent, Context context) { this.agent = agent; this.context = context; } @JavascriptInterface public void callAndroid(final String msg) { deliver.post(new Runnable() { @Override public void run() { Log.i("Info", "m

 36 |  0 |  0 vueAndroid

蓝皮鼠 | 1周前 | 流媒体协议

深入了解NAT穿透技术

引言 通过此文更加深入的总结NAT穿透技术,其中涉及到NAT,STUN协议,TURN协议,ICE协议。 NAT NAT概念 在计算机网络中,网络地址转换(Network Address Translation,缩写为NAT),也叫做网络掩蔽或者IP掩蔽(IP masquerading),是一种在IP数据包通过路由器或防火墙时重写来源IP地址或目的IP地址的技术。这种技术被普遍使用在有多台主机但只通过一个公有IP地址访问因特网的私有网络中。1990年代中期,NAT是作为一种解决IPv4地址短缺以避免保留IP地址困难的方案而流行起来的。 NAPT概念 NAT虽然名为网络地址转换,但是常见的工作模式实际上是NAPT(网络地址端口转换)。这种方式支持端口的映射,并允许多台主机共享一个公网IP地址。 支持端口转换的NAT又可以分为两类:源地址转换和目的地址转换。前一种情形下发起连接的计算机的IP地址将会被重写,使得内网主机发出的数据包能够到达外网主机。后一种情况下被连接计算机的IP地址将被重写,使得外网主机发出的数据包能够到达内网主机。实际上,以上两种方式通常会一起被使用以支持双向通信。NAPT维护一个带有IP以及端口号的NAT表,结构如下: | 内网IP&Port | 外网IP&Port | |-------------------|----------------------| | 192.168.1.55:5566 | 219.152.168.222:9200 | | 192.168.1.59:80 | 219.152.168.222:9201 | | 192.168.1.59:4465 | 219.152.168.222:9202 | 不同类型的NAT 完全圆锥形NAT Full cone NAT(即一对一NAT): 一旦一个内部地址(iAddr:iPort)映射到外部地址(eAddr:ePort),所有发自(iAddr:iPort)的包都经由(eAddr:ePort)向外发送。任意外部主机都能通过给(eAddr:ePort)发包到达(iAddr:iPort)。 ![32f061712c34487698c4b07343bf892c](https://qiniu.qjos.cn/32f061712c34487698c4b07343bf892c.jpe...

 48 |  0 |  0 流媒体协议

蓝皮鼠 | 2周前 | Android安卓优化

android 优化之10种保活App方案

1.Activity 1像素保活 js public class Activity1 extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_1); Window window = getWindow(); window.setGravity(Gravity.LEFT|Gravity.TOP); WindowManager.LayoutParams layoutParams = window.getAttributes(); layoutParams.width = 1; layoutParams.height = 1; layoutParams.x = 1; layoutParams.y = 1; window.setAttributes(layoutParams); } } 2.前台服务 js public class ForegroundService extends Service { private final static int SERVICE_ID = 1; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); if (Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN_MR2){ //4.3以下 startForeground(SERVI

 54 |  0 |  0 Android安卓优化

二次元码农 | 2周前 |

android 开发中怎么设置相机的焦距?

1、添加Camera权限 当使用相机时,除了需要在AndroidManifest文件中添加相应的权限 <uses-permission android:name="android.permission.CAMERA"/ 在代码需要调用相机部分做如下修改: //运行时权限 java if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CAMERA},1); }else { startActivityForResult(new Intent(MainActivity.this, CaptureActivity.class),0); } 2、判断是否支持变焦 java public boolean isSupportZoom() { boolean isSuppport = true; if (mCamera.getParameters().isSmoothZoomSupported()) { isSuppport = false; } return isSuppport; } 3、修改焦距 java public void setZoom() { if (mIsSupportZoom) { try { Parameters params = mCamera.getParameters(); final int MAX = params.getMaxZoom();           if(MA

 41 |  0 |  0

二次元码农 | 2周前 | Android

android 初始化页面报 Fail to connect to camera service 原有分析

在应用开发中涉及到camera相关的操作经常会出现 Fail to connect to camera service 的问题,相应的也就会出现上面类似的错误异常日志。 下面就出现这个错误的场景和原因简单做下分析。 1.手机上有安装安全过滤软件。因为camera属于较为敏感的权限,所以,有些手机安全管家会自动拒绝camera的打开操作。 针对这种错误,可以在手机安全管家软件中,降低一下camera的安全级别,或把自己的APP添加到白名单中。 2.AndroidManifest.xml中没有添加camera的权限申请,对策则是添加<uses-permission android:name="android.permission.CAMERA"/ 权限申请。 3.之前对camera打开后,并没有释放掉。 解决对策就是调用下面的处理 camera.stopPreview(); camera.release(); camera = null; 4.内存占用过多,可能导致了自己应用可分配的内存不足了。 这个场景的错误差不多是在自己的应用中打开摄像头,对摄像头取得的每一帧数据都进行额外的处理,随着处理次数的增加,如果有没被及时销毁的对象存在,则就极有可能会导致本文开头出现的异常了。 针对此种问题,解决的方法就是仔细检查下临时创建的对象是否都已经释放掉。

 64 |  0 |  0 Android

蓝皮鼠 | 2周前 | Android

Android 查看SD卡是否存在以空间总容量和剩余容量

如何查看Android挂载的SD卡是否存在?以及该SD卡的空间总容量和剩余容量? 1.配置SD卡权限 首先要在AndroidManifest.xml中增加SD卡访问权限 java <!- 在SDCard中创建与删除文件权限 - <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/ <!- 往SDCard写入数据权限 - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/ 2.判断SD卡是否存在 java private boolean ExistSDCard() { if (android.os.Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED)) { return true; } else return false; } 3.查看SD卡剩余空间 java public long getSDFreeSize(){ //取得SD卡文件路径 File path = Environment.getExternalStorageDirectory(); StatFs sf = new StatFs(path.getPath()); //获取单个数据块的大小(Byte) long blockSize = sf.getBlockSize(); //空闲的数据块的数量 long freeBlocks = sf.getAvailableBlocks(); //返回SD卡空闲大小 //return freeBlocks blockSize; //单位Byte //return (freeBlocks blockSize)/1024; //单位KB retu

 68 |  1 |  2 Android

蓝皮鼠 | 2周前 | Android

Android获取设备号SSAID (Android ID) 和 IMEI

1、基本方式 java / 获取手机的设备号. @param context 上下文 @return 设备号 / @SuppressLint("HardwareIds") public static String getIMEIDeviceId(Context context) { String deviceId; //如果sdk版本大于等于29 if (Build.VERSION.SDK_INT = Build.VERSION_CODES.Q) { deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); } else { final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (Build.VERSION.SDK_INT = Build.VERSION_CODES.M) { if (context.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { return ""; } } assert mTelephony != null; if (mTelephony.getDeviceId() != null) { if (Build.VERSION.SDK_INT = Build.VERSION_CODES.O) { deviceId = mTelephony.

 55 |  0 |  0 Android

蓝皮鼠 | 3周前 | Android

浅谈Android中service服务生命周期及启动方式的区别

一、生命周期: startService启动方式: java onCreate()— onStartCommand() — onDestroy(); bindService启动方式: java onCreate()— onBind() — onUnbind()— onDestroy(); 我们通过官方给出的一张图片来体会一下: 二、启动方式(基本使用方法): startService: java Intent mIntent=new Intent(MainActivity.this,startServiceDemo.class) ; startService(mIntent);//直接启动服务方式启动 stopService(mIntent);//停止服务 bindService: js ServiceConnection serviceConnection=new myServiceConnect(); Intent mBindIntent=new Intent(MainActivity.this,bindServiceDemo.class); bindService(mBindIntent,serviceConnection,BIND_AUTO_CREATE); unbindService(serviceConnection); 实现ServiceConnection接口 java public class myServiceConnect implements ServiceConnection { //绑定成功之后回调,Service中传递的数据,在此中接收 @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { } @Override public void onServiceDisconnected(ComponentName componentName) { } } 三、启动方式区别: 1、生命周期的不同:startService生命周期为onCreate 2、重复调用是调用方法不同: st

 84 |  0 |  0 Android

蓝皮鼠 | 3周前 | Android

OkHttp3实现WebSocket连接

项目中有一个IM模块,是使用了WebSocket来做的,特此记录一下。 WebSocket的框架有很多,了解到OkHttp3也有支持WebSocket,就采用了Okhttp来实现。 一个是不需要再引入多一个WebSocket的第三方库,一个是Okhttp3口碑和稳定性都非常好,而且还一直在更新。 添加依赖 java implementation 'com.squareup.okhttp3:okhttp:3.8.1' 实现步骤 构建OkHttpClient配置初始化一些参数。 使用WebSocket的Url地址连接。 设置WebSocket的连接状态回调和消息回调。 解析消息json处理业务等。 连接成功后,使用WebSocket发送消息 配置OkHttpClient java OkHttpClient mClient = new OkHttpClient.Builder() .readTimeout(3, TimeUnit.SECONDS)//设置读取超时时间 .writeTimeout(3, TimeUnit.SECONDS)//设置写的超时时间 .connectTimeout(3, TimeUnit.SECONDS)//设置连接超时时间 .build(); 使用Url,构建WebSocket请求(一般是后端接口返回连接的Url地址) //连接地址 String url = "ws://xxxxx" //构建一个连接请求对象 Request request = new Request.Builder().get().url(url).build(); 发起连接,配置回调。 onOpen(),连接成功 onMessage(String text),收到字符串类型的消息,一般我们都是使用这个 onMessage(ByteString bytes),收到字节数组类型消息,我这里没有用到 onClosed(),连接关闭 onFailure(),连接失败,一般都是在这里发起重连操作 //开始连接 WebSocket websocket = mClient.newWebSocket(request, new WebSocketListener() { @Overri

 97 |  0 |  0 Android

蓝皮鼠 | 3周前 | Android

Android获取手机硬件信息(CPU、内存)工具类

kotlin版 java import android.app.ActivityManager import android.content.Context import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io. / 获取硬件信息工具类,如:CPU参数、内存参数等 / class HardwareInfoUtils { //获取CPU整体温度,单位:°C suspend fun getCPUTemperature() : Float{ var temperature : String withContext(Dispatchers.IO){ val temperatureOfCPUFileName = "/sys/class/thermal/thermal_zone0/temp" temperature = readCpuInfo(temperatureOfCPUFileName) } return temperature.toFloat()/1000.0F ?: 0.00F } / 获取CPU整体使用率,返回是"百分比" 如返回:22.0,表示CPU占用率是22.0% / suspend fun getCPUUsage() : Float{ var rate : Float = 0.00f withContext(Dispatchers.IO){ var process : Process? = null try{ process = Runtime.getRuntime().exec("top -n 1") val reader : BufferedReader = BufferedReader( InputStreamReader(process.inputStream)

 63 |  0 |  0 Android

蓝皮鼠 | 3周前 | Android

Android 性能优化之弱引用 (WeakReference)的使用

1 弱引用 (WeakReference) 弱引用对象,这些对象不会阻止对其引用对象进行终结,终结和回收。弱引用最常用于实现规范化映射。假设垃圾收集器在某个时间点确定对象是弱可到达的。到那时,它将自动清除对该对象的所有弱引用以及对所有其他弱可达对象的弱引用,这些对象都可以通过一系列强引用和软引用从该对象到达。同时,它将声明所有以前弱可及的对象都是可终结的。同时或稍后,它将把那些新近清除的弱引用加入队列,这些弱引用已在引用队列中注册 简单的理解就是:弱引用用来描述非必须对象的,当gc进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。 1.1 下面以定义一个String 对象来说下弱引用 (WeakReference)的使用 java WeakReference<String str = new WeakReference< ("弱引用"); Log.e("---------str", str.get()); 1.2 加载一个图片的demo 先看下普通的使用 java Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.image); Drawable drawable = new BitmapDrawable(bitmap); imageView.setBackground(drawable); 如果使用弱引用 (WeakReference)如下 java Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.image); Drawable drawable = new BitmapDrawable(bitmap); WeakReference<Drawable weakDrawable = new WeakReference< (drawable); Drawable bgdrawable = weakDrawable.get(); if(bgdrawable != null) { imageVie

 71 |  0 |  0 Android

蓝皮鼠 | 3周前 | Android

Android 实现Service悬浮窗监听实时网速

我们都知道Android 的Service一般情况下是没有界面的,也就是运行在后台看不见的地方,实际上Service也可以是可见的,这篇文章简单记录一下如何让Service可见。 在安卓8以后显示悬浮窗需要动态申请“在其他应用上显示悬浮窗”权限,所以我们首先需要申请这一个权限,在manifest文件中添加一下权限: java <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" / 接下来是在APP启动时申请显示悬浮窗的权限,当检查到没有权限的时候会自动跳转到系统设置界面: java if (Build.VERSION.SDK_INT = 23) { if (!Settings.canDrawOverlays(this)) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivityForResult(intent, 1); } else { Log.e("TAG", "H"); //TODO do something you need } } 接下来就是Service的创建,在onCreate()方法中创建对应的弹窗布局,并显示: java private NetSpeedTask netSpeedTask; private Timer timer; private NetSpeedUtil netSpeedUtil; private LinearLayout linearLayout; private TextView textView; private WindowManager windowManager;

 72 |  0 |  0 Android

蓝皮鼠 | 3周前 | Android

Android实时检测网络(流量监控)代码实现

创建工具类 java import android.content.Context; import android.net.TrafficStats; import android.os.Handler; import android.os.Message; import java.util.Timer; import java.util.TimerTask; / @ClassName: NetWorkListenerUtils @Description: 实时网络流量检测 @Author: 有时有晌 @Date: 2022/3/14 10:13 / public class NetWorkListenerUtils { private Context context; private Handler mHandler; private long lastTotalRxBytes = 0; private long lastTimeStamp = 0; private Timer timer; public NetWorkListenerUtils(Context context, Handler mHandler) { this.context = context; this.mHandler = mHandler; } public void startShowNetSpeed() { lastTotalRxBytes = getTotalRxBytes(); lastTimeStamp = System.currentTimeMillis(); // 1s后启动任务,每2s执行一次、 if (timer null) { timer=new Timer(); } timer.schedule(task, 1000, 1000); } public void unbindShowNetSpeed() { if (timer != null) {

 73 |  0 |  0 Android

蓝皮鼠 | 3周前 | mysql

MySQL主从复制应用场景有哪些?

MySQL主从复制集群功能使得MySQL数据库支持大规模高并发读写成为可能,同时有效地保护了物理服务器宕机场景的数据备份。那么MySQL主从复制的企业应用场景有哪些?Linux运维工作人员要注意什么? 1、从服务器作为主服务器的实时数据备份 主从服务器架构的设置可以大大加强MySQL数据库架构的健壮性。利用MySQL的复制功能进行数据备份时,在硬件故障、软件故障的场景下,该数据备份是有效的,但对于人为地执行drop、delete等语句删除数据的情况,从库的备份功能就没用了,因为从服务器也会执行删除的语句。 2、主从服务器实现读写分离,从服务器实现负载均衡 主从服务器架构可通过程序或代理软件实现对用户(客户端)的请求读写分离,即让从服务器仅仅处理用户的select查询请求,降低用户查询响应时间,以及同时读写在主服务器上带来的访向压力。对于更新的数据,则仍然交给主服务器处理,确保主服务器和从服务器保持实时同步。 大多数的网站都是用户浏览页面多于用户发布内容,因此通过在从服务器上接收只读请求,就可以很好地减轻主库的读压力,且从服务器可以很容易地扩展为多台,使用LVS做负载均衡效果就非常棒了,这就是传说中的数据库读写分离架构。 3、把多个从服务器根据业务重要性进行拆分访问 可以把几个不同的从服务器,根据公司的业务进行拆分。例如:有为外部用户提供查询服务的从服务器,有内部DBA用来数据备份的从服务器,还有为公司内部人员提供访问的后台、脚本、日志分析及供开发人员查询使用的从服务器。这样的拆分除了减轻主服务器的压力外,还可以使数据库对外部用户浏览、内部用户业务处理及DBA人员的备份等互不影响。

 80 |  0 |  0 mysql

蓝皮鼠 | 3周前 | mysql

mysql主从复制三种模式

MySQL的复制是利用二进制日志binlog实现主从之间的数据同步。binlog日志的格式分为三种,使用参数binlog_format控制binlog的格式,该参数的不同值代表不同的日志格式,三种日志格式对应三种主从复制模式: 语句复制模式(Statement Based Replication,SBR):基于实际执行的SQL语句的复制模式,该复制模式简单实现了数据同步,但在执行跨库更新等SQL语句时容易出现主从库的数据不一致问题。 记录复制模式(Row Based Replication,RBR):基于修改的行的复制模式。不再简单记录SQL语句的执行顺序,而是逐行记录存储引擎的数据是如何变更的,主从库的数据一致性保障得到大幅度提升,是当前各生产环境常用的一种复制模式,该方式更安全。 混合复制模式(Mixed Based Replication):简称MBR,根据SQL语句的不同来判断是否需要使用row格式,当出现可能造成主从库数据不一致的SQL语句时(例如:用户自定义函数、跨库SQL语句等),binlog自动转为row格式记录。 查看binlog_format参数值: mysql show global variables like 'binlog_format'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | binlog_format | ROW | +---------------+-------+ 1 row in set (0.08 sec) mysql 下面展示如何在mysql实例层设置该参数值: 设置为statement格式: mysql set global binlog_format=statement; Query OK, 0 rows affected (0.00 sec) 设置为mixed格式: mysql set global binlog_format=mixed; Query OK, 0 rows affected (0.00 sec) 设置为row格式: mysql set global binlog_format=row; Query OK, 0 rows affected (0.00 sec) ...

 61 |  0 |  0 mysql

蓝皮鼠 | 4周前 | Android

Android页面静置一段时间后okhttp请求失败

okhttp连接timeout 最近遇到的一个问题: 控制台报错:java.io.IOException: unexpected end of stream on …(地址) at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders 一开始没有查看日志,长时间未进行网络请求后,再次切换页面并请求数据,便会出现连接失败的问题,猜测是不是Android系统版本比较低,页面长时间未触摸从而导致网络断开,或者是connectTimeout时间设置的问题,待查看日志之后,出现上面的错误。 由此找出两个可能性:1、本地设置的timeout时间大于服务器timeout时间; 2、与okhttp和版本都有关系,需要在拦截器中增加一个addHeader(“Connection”,“close”)。 java //拦截器内添加addHeader("Connection","close") Request request = chain.request().newBuilder() .addHeader("Connection","close").build(); Response response = chain.proceed(request); kava private static final OkHttpClient client = new OkHttpClient.Builder() .retryOnConnectionFailure(false) .connectionPool(new ConnectionPool(500, 20, TimeUnit.MINUTES)) .connectTimeout(300, TimeUnit.SECONDS) .readTimeout(300, TimeUnit.SECONDS) .writeTimeout(300, TimeUnit.SECONDS) .addInterceptor(new NetInterceptor())

 137 |  1 |  1 Android

蓝皮鼠 | 4周前 | Android

android 异常java.io.IOException: unexpected end of stream on Connection 解决

异常 java.io.IOException: unexpected end of stream on Connection 原因 客户端和服务器通过TCP协议进行连接,第一次请求成功后,客户端复用了原来的连接,但服务器此时已经处在TCP连接中的FIN_WAIT2状态,因此连接不成功。 解决 把retryOnConnectionFailure()设置成true,或者保持okhttpClient默认设置(即删除这个设置,默认是true)

 76 |  0 |  0 Android

蓝皮鼠 | 4周前 | Android

Android8.0利用JobScheduler实现服务的运行

Android8.0利用JobScheduler实现服务的运行 从Google Play要求全部应用最低的目标sdk版本为26开始,更改后台服务就被提上了日程。官方推荐的是使用JobScheduler,它能够根据指定的各类条件,更好的为用户处理网络相关的做业。当声明的条件知足时,由系统在应用进程中执行该工做。javaJobScheduler+JobInfo+JobService JobScheduler主要负责任务调度。JobInfo描述了任务的概要信息,传递给JobScheduler彻底封装调度应用程序调度工做所需参数的数据容器。JobService则用来处理任务。JobScheduler是在API21中才有的,因此使用JobScheduler须要添加判断,在API =21的时候,选择使用JobService的方式启动服务。具体的一些方法说明能够查阅官方文档,这里主要说明具体的用法。 建立JobInfo java / 建立jobInfo @param jobId 任务的标识符 惟一 @param componentName jobService类 @param requestInterval 请求间隔 / @TargetApi(Build.VERSION_CODES.LOLLIPOP) public JobInfo buildJobInfo(int jobId, ComponentName componentName, long requestInterval) { //表明一个任务 使用建造者模式建造 JobInfo jobInfo; // Android7上,设置周期执行时间,会强制按照getMinPeriodMills阈值执行,此时设置任务执行最小时间间隔解决该问题 if(Build.VERSION.SDK_INT = Build.VERSION_CODES.N) { android.util.Log.d("jobService", "buildJobInfo: minimum"); jobInfo = new JobInfo.Builder(jobId,com

 79 |  0 |  0 Android

蓝皮鼠 | 4周前 |

spring cloud基础(入门小知识)

SOA SOA (Service-Oriented Architecture ),也就是⾯向服务的架构,从语 义上说,它和⾯向过程、⾯向对象、⾯向组件的思想是⼀样的,都是⼀种软件组建及开发的⽅式 核⼼⽬标是把⼀些通⽤的、会被多个上层服务调⽤的共享业务提取成独⽴的基础服务。这些被提取出来的共 享服务相对来说⽐较独⽴,并且可以重⽤。所以在SOA中,服务是最核⼼的抽象⼿段,业务被划分为⼀ 些粗粒度的业务服务和业务流程。 提取出了⽤户服务、库存服务、商品服务等多个共享服务。在SOA中,会采⽤ESB (企业服务总线)来作为系统和服务之间的通信桥梁,ESB本身还提供服务地址的管理、不同系统之间 的协议转化和数据格式转化等。调⽤端不需要关⼼⽬标服务的位置,从⽽使得服务之间的交互是动态 的,这样做的好处是实现了服务的调⽤者和服务的提供者之间的⾼度解耦。 ![970960547d5e459ca8d4115de524eb3e](https://qiniu.qjos.cn/970960547d5e459ca8d4115de524eb3e.png) 总的来说,SOA主要解决的 问题是: 信息孤岛。 共享业务的重⽤。 1、springcloud基础 1.1什么是微服务 一种架构风格。 开发单个应用作为一系列小型服务的套件,其中每个服务都运行在自己的进程中,并且通过轻量级的机制实现彼此间的通信, 这通常是HTTP资源API。 这些服务是围绕着业务功能构建的,并且可以通过完全自动化 的部署机制进行独立部署。 这些服务的集中式管理做到了最小化(例如docker相关技 术),每一种服务都可以通过不同的编程语言进行编写,并且 可以使用不同的数据存储技术。 1.2微服务的特点 总结微服务应具有如下特点 微服务是⼀种架构⻛格。 微服务把⼀个应⽤拆分为⼀组⼩型服务。 微服务每个服务运⾏在⾃⼰的进程内,也就是可独⽴部署和升级。 微服务的服务之间使⽤轻量级HTTP交互,⼀般使⽤Json交换数据。 服务围绕业务功能拆分。 可以由全⾃动部署机制独⽴部署。 去中⼼化,服务⾃治。服务可以使⽤不同的语⾔、不同的存储技术 。 1.3微服务的优缺点 优点: 服务简单,便于学习和上手,相对容易维护 独立部署,灵活扩展 技术栈丰富,不同模块之间可以使用不同的技术 缺点 运维成本太高----需要过多的服务器...

 71 |  0 |  0

蓝皮鼠 | 4周前 | Android

Android性能优化方案(持续总结)

Android中的性能优分为以下几个方面: 布局优化 网络优化 安装包优化 内存优化 卡顿优化 启动优化 …… 一.布局优化布局优化的本质就是减少View的层级。常见的布局优化方案如下: 在LinearLayout和RelativeLayout都可以完成布局的情况下优先选择LinearLayout,可以减少View的层级,但是注意相同组件可能RelativeLayout绘制时间长 使用 < include 标签将常用的布局组件共同的部分抽取出来,以便复用。 通过 < ViewStub 标签来加载不常用的布局,延迟加载(需要的时候在activity中加载出来) 使用 < Merge 标签来减少布局的嵌套层次 二.绘制优化 绘制优化是指View的onDraw方法要避免执行大量的操作,这主要体现在两个方面: 1.onDraw中不要创建新的局部对象。 因为onDraw方法可能会被频繁调用,这样就会在一瞬间产生大量的临时对象,这不仅占用了过多的内存而且还会导致系统更加频繁gc,降低了程序的执行效率。 2.onDraw方法中不要做耗时的任务, 不能执行成千上万次的循环操作,尽管每次循环都很轻量级,但是大量的循环仍然十分抢占CPU的时间片,这会造成View的绘制过程不流畅。 按照Google官方给出的性能优化典范中的标准,View的绘制频率保证60fps是最佳的,这就要求每帧绘制时间不超过16ms(16ms = 1000/60),虽然程序很难保证16ms这个时间,但是尽量降低onDraw方法中的复杂度总是切实有效的。 三.网络优化 常见的网络优化方案如下: 尽量减少网络请求,能够合并的就尽量合并 避免DNS解析,根据域名查询可能会耗费上百毫秒的时间,也可能存在DNS劫持的风险。可以根据业务需求采用增加动态更新IP的方式,或者在IP方式访问失败时切换到域名访问方式。 大量数据的加载采用分页的方式 网络数据传输采用GZIP压缩 加入网络数据的缓存,避免频繁请求网络 上传图片时,在必要的时候压缩图片 四.安装包优化 安装包优化的核心就是减少apk的体积,常见的方案如下: 减少应用中不必要的资源文件,比如图片,在不影响APP效果的情况下尽量压缩图片,有一定的效果 在使用了SO库的时候优先保留v7版本的SO库,删掉...

 82 |  0 |  0 Android