• Unity 和 Android 混合开发更友好的方案

    前言

    在网上搜索 Unity 和 Android 的混合开发,一般可以查到,大致分为两种方案:

    1. 以 Unity 主导的开发,Android 提供 JAR 包或 AAR 包,导入到 Unity 作为插件,最后由 Unity 开发打包 APK;(对 Unity 技能要求高点)

    2. 以 Android 主导的开发,Unity 导出 Android 项目,再以 Module 方式或 AAR 方式引入到 Android 工程项目中,最后由 Android 开发打包 APK;(对Android 技能要求高点)

    但是这两种方式都有不足的地方:

    • 方式1,对 Android 开发人员不够友好,Android 工程,只能运行 Android 端的代码,不能同步 Unity 端代码,每次 Android 端修改代码都要导出包给 Unity 开发,通过 Unity 来调试;另外,如果有依赖第三方库,每次改完Android 工程的,还得修改 Unity 的 Android 插件配置的;(使用常规的方式,第三方库不支持打包进 aar)

    • 同样,方式2,对 Unity 开发人员不够友好,Unity 端只能运行 Unity 代码,不能同步运行 Android 端代码,每次改完都要导包给 Android 端验证;

    这两种方式,都增加了 Android 端和 Unity 端的开发测试成本(只能单方开发测试)和沟通成本(虽然导包给对方的流程可以直接通过 Git 上传包文件到对方的项目工程,但开发阶段,需要太频繁上传包来测试,频繁沟通也挺费时间的)。需要三个Git 工程:Unity 工程、Unity 导出的 Android 工程、Android 工程。

  • Kotlin 开发小 tips

    总结下,最近开发中使用 Kotlin 的一些小 tips。

    1. 尽可能使用 val 声明 Kotlin 的变量。

    val 声明的变量表示不可变的,必须初始化,其他地方不能修改该值,是线程安全的。  

    2. Elvis操作符 ?:

    在无法判断变量是否有可能为空的情况下,不要写成显式的非 null 操作符 !!,尽量用 Elvis操作符 ?: ,特别是数值类型的时候,
    如  var count = list?.length ?: 0

    3. 尽量不要使用非空断言 !! (除非确保变量不为空)

    可以使用 ? , ?: 或 lateinit 来避免编译器的可空提示
    但使用 lateinit 时,务必确保使用的时候已经赋值(否则会报 kotlin.UninitializedPropertyAccessException: lateinit property bitmap has not been initialized 异常),并且确保赋的值一定不能为空(lateinit定义的值是非空的)

  • 浅谈项目中需求变更和拖延的问题

    站在移动端开发人员的角度,谈谈项目开发中产品经理该如何更合理地处理需求变更和项目拖延的问题。(以前团队内部分享总结的,重新发出来)

    引子:当开发人员说“技术无法实现”的时候,是想表达什么?

    • 需求太傻了,完全没必要做;

    比如那种根据手机壳颜色变换主题颜色的功能。

    • 时间和资源不够,成本太高,不想去做;

    比如项目周期就两个月,自研 IM 的功能根本完成不了,而且实现的效果未必有第三方IM功能好。

    • 从项目代码上改动太大,开发人员不愿做;

    比如,之前遇到一个需求:应用所有页面除了以下两种情况其余都可以调起摇一摇客服弹窗:已经有弹窗出现的时候,不能调起摇一摇客服弹窗;在客服页面或引导蒙层页面,不能调起。按照常规的实现方式,需要每个页面和每个对话框都去实现一遍是否启动摇一摇客服的逻辑,这样代码改动会很大;如果之前的页面逻辑时每个页面或对话框都是继承一个 Base 类,那实现起来就简单很多。

  • 如何提高工作中的开发效率?

    注: 以下不提过多技术层面的技巧,更多的是工作方式。

    积极沟通,理解产品需求;主动对接,减少不必要的等待;学会搜索,培养一套自己的开发流程。

    如果项目中大多只是做业务开发,涉及到的技术难点不多,只是业务逻辑比较复杂的话,那整个开发流程真正花在编码的时间其实是不多的,大部分时间花在以下几方面:

    • 了解清楚业务需求,开发中和 PM 沟通一些需求的细节问题;
    • 等待 UI 设计师完成设计图或切图;
    • 等待后端开发写好接口文档或进行接口的联调;
    • 开发过程中的需求变更或增加新需求;

    那如何减少这些开发流程中花费的时间,从而提高开发效率呢?我觉得可以从以下几方面去考虑:

  • Android NDK 开发:CMake 使用

    1. 前言

    当在做 Android NDK 开发时,如果不熟悉用 CMake 来构建,读不懂 CMakeLists.txt 的配置脚本,很容易就会踩坑,遇到编译失败,一个很小的配置问题都会浪费很多时间。所谓工欲善其事必先利其器,学习 NDK 开发还是要大致了解 CMake 的基本语法和配置的。下面文章是根据 CMake 实践手册 做的一些简短笔记,具体说得不够详细的地方,可以查看手册。

    2. CMake 是什么?

    CMake 是一个开源的跨平台自动化构建系统。官网地址:CMake

    2.1CMake 的特点

    • 1)开放源代码,使用类 BSD 许可发布。
    • 2)跨平台,并可生成 native 编译配置文件,在 Linux/Unix 平台,生成 makefile,在
      Mac 平台,可以生成 xcode,在 Windows 平台,可以生成 MSVC 的工程文件。
    • 3)能够管理大型项目;
    • 4)简化编译构建过程和编译过程。Cmake 的工具链非常简单:cmake+make。
    • 5)高效率;
    • 6)可扩展,可以为 cmake 编写特定功能的模块,扩充 cmake 功能。
  • Android NDK 开发:实战案例

    0. 前言

    如果只学理论,不做实践,不踩踩坑,一般很难发现真正实践项目中的问题的,也比较难以加深对技术的理解。所以延续上篇 JNI 的实战Android NDK开发:JNI实战篇 ,这篇主要是一些 NDK 小项目的练习,由于这些项目网上都有 demo介绍,这里不会具体一步步介绍如何操作,只记录一些个人需要注意的地方或一些主要步骤,详细的介绍或代码可以点击里面的链接查看。

    1. 文件加解密和分割合并

    1.1 简介

    所有文件都是二进制存储的,无论是文本,图片还是视频文件都是以二进制存储在磁盘中。所以可以通过对文件进行二进制运算进行加解密。下面用到的是比较简单的^异或运算来对文件加解密(算是一种对称加密算法)
    附:加解密算法扩展:加解密算法 · 区块链技术指南

    一般在大文件传输时,如音视频文件,会将文件分割后再传输,从而提高效率。当需要使用时,再将分割后的文件合并即可。

    而文件加解密设计到安全,可以使用 NDK 增加反编译的难度。另外文件的分割合并都比较耗性能,可以放到 NDK 处理提高效率。

  • Android NDK开发:JNI实战篇

    紧接上篇:Android NDK开发:JNI基础篇 | cfanr,这篇主要介绍 JNI Native 层调用Java 层的代码(涉及JNI 数据类型映射和描述符的使用)和如何动态注册 JNI。

    1. Hello World NDK

    在开始实战练习前,你需要先大致了解运行一个 Hello World 的项目大概需要做什么,有哪些配置以及配置的具体意思。 Android Studio(2.2以上版本)提供两种方式编译原生库:CMake( 默认方式) 和 ndk-build。对于初学者可以先了解 CMake 的方式,另外,对于本文可以暂时不用了解 so 库如何编译和使用。

    一个 Hello World 的 NDK 项目很简单,按照流程新建一个 native 库工程就可以,由于太简单,而且网上也有很多教程,这里就没必要浪费时间再用图文介绍了。详细操作方法,可以参考这篇文章,AS2.2使用CMake方式进行JNI/NDK开发-于连林- CSDN博客

    列出项目中涉及 NDK 的内容或配置几点需要注意的地方:

    • .externalNativeBuild 文件是 CMake 编译好的文件,显示支持的各种硬件平台的信息,如 ARM、x86等;
    • cpp 文件是放置 native 文件的地方,名字可以修改成其他的(只要里面函数名字对应Java native 方法就好);
    • CMakeLists.txt,AS自动生成的 CMake 脚本配置文件
  • Android NDK开发:JNI基础篇

    1. JNI 概念

    1.1 概念

    JNI 全称 Java Native Interface,Java 本地化接口,可以通过 JNI 调用系统提供的 API。操作系统,无论是 Linux,Windows 还是 Mac OS,或者一些汇编语言写的底层硬件驱动都是 C/C++ 写的。Java和C/C++不同 ,它不会直接编译成平台机器码,而是编译成虚拟机可以运行的Java字节码的.class文件,通过JIT技术即时编译成本地机器码,所以有效率就比不上C/C++代码,JNI技术就解决了这一痛点,JNI 可以说是 C 语言和 Java 语言交流的适配器、中间件,下面我们来看看JNI调用示意图:来自JNI开发系列①JNI概念及开发流程 - 简书

  • Android开发的C++基础Notes

    前言:下文是很基础的C++语法的 notes,只是个人学习 C++时,针对自己不熟悉的知识点做的零散的笔记,方便后期阅读。对于很熟悉 C++的人来说,不具备阅读价值。

    学习教程:C++ 教程 | 菜鸟教程

    1. 局部变量和全局变量初始化问题

    当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动初始化为下列值,int - 0, char- ‘\0’,float - 0 等

    2. 定义常量方式

    C++中有两种方式, C++ 常量 | 菜鸟教程

    • 使用宏定义#define预处理器(不需要分号,不需要声明类型
      形式:#define identifier value,如 # define LENGTH 10
    • 使用 const 关键字
      形式:const type variable = value;
      常量名定义和 Java 一样,最好使用大写字母形式,同时注意常量定义必须有值,也不能被重新赋值(不然就不叫常量了)
  • 微信 Mars Android Sample 源码分析

    整个 Sample 提供了以下功能:

    • 基于TCP长连接的聊天室体验。
    • 数据通信成功率、耗时、流量的展示。
    • 网络状况检测结果展示。

    一、本地运行 Server 端

    具体如何运行 Server 端,参照官方wiki:Mars Sample 使用说明

    二、修改 Android Sample

    下面说下Android 端该如何修改源码连接到本地服务器

    • 1.全局搜索marsopen.cn,修改替换为localhost
    • 2.在保证 app/build.gradleuseLocalMarsWrapper = true的情况下,在 wrapper module 下修改 com.tencent.mars.sample.wrapper.service. MarsServiceStub.java 的 dns 解析的地址为本地主机的 IP 地址 (wiki 上没写清楚)
      1
      2
      3
      4
      5
      @Override
      public String[] onNewDns(String host) {
      // No default new dns support
      return new String[]{"192.168.24.193"}; //替换为本地主机的 IP 地址
      }