安卓知识汇总

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/likuan0214/article/details/79417745

1.Walle(瓦力,美团开源的)通过在Apk中的APK Signature Block区块添加自定义的渠道信息来生成渠道包,从而提高了渠道包生成效率,可以作为单机工具来使用,也可以部署在HTTP服务器上来实时处理渠道包Apk的升级网络请求。

2.图片内存的计算
计算公式:
所占内存 = 图片长度 * 图片宽度 * 每个像素所占的内存
ALPHA_8:每个像素点占用1byte内存
ARGB_4444:每个像素点占用2byte内存
ARGB_8888: 每个像素点占用4byte内存
RGB_565: 每个像素点占用2byte内存

3.http
http://www.blogjava.net/zjusuyong/articles/304788.html
http://blog.csdn.net/java173842219/article/details/54020168
https://www.cnblogs.com/sharpest/p/7831350.html
http://blog.csdn.net/zhuwukai/article/details/78644484

4.数据库
继承SQLiteOpenHelper,重写onCreate(创建数据库)和onUpgrade(更新数据看)两个方法。
使用:

public class MySql extends SQLiteOpenHelper {

    private static final int DB_VERSION = 2;
    private static final String DB_NAME = "myTest.db";
    public static final String TABLE_NAME = "Orders";
    public static final String _ID = "_id";
    public static final String ORDER_ID = "Id";
    public static final String ORDER_NAME = "CustomName";
    public static final String ORDER_PRICE = "OrderPrice";
    public static final String ORDER_COUNTRY = "Country";

    public MySql(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "create table if not exists " + TABLE_NAME + " (_id integer primary key autoincrement,"+ ORDER_ID +" integer, "+ ORDER_NAME +" text, " + ORDER_PRICE + " integer, " + ORDER_COUNTRY + " text)";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String sql = "DROP TABLE IF EXISTS " + TABLE_NAME;
        db.execSQL(sql);
        onCreate(db);
    }
}
    MySQLiteOpenHelper mysql = new MySQLiteOpenHelper(context);
    SQLiteDatabasedb = mysql.getWritableDatabase();


execSQL(String sql)
public long insert(String table, String nullColumnHack, ContentValues values)

int delete(String table, String whereClause, String[] whereArgs)

int update(String table, ContentValues values, String whereClause, String[] whereArgs)

Cursor query(String table, String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy)
Cursor rawQuery(String sql, String[] selectionArgs)
要注意Cursor使用后要及时关闭,否则会内存泄漏

示例:

    @Override
    public void execSQL(int orderid, String name, int price, String country) {
        db.beginTransaction();

        db.execSQL("insert into " + MySql.TABLE_NAME
                + " (" + MySql.ORDER_ID + ", " + MySql.ORDER_NAME + ", " + MySql.ORDER_PRICE + ", " + MySql.ORDER_COUNTRY + ") values ("
                + orderid + ", '" + name + "', " + price + ", '" + country + "')");

        db.setTransactionSuccessful();
        db.endTransaction();
    }

    @Override
    public void insert(int orderid, String name, int price, String country) {
        db.beginTransaction();

        ContentValues values = new ContentValues();
        values.put(MySql.ORDER_ID, orderid);
        values.put(MySql.ORDER_NAME, name);
        values.put(MySql.ORDER_PRICE, price);
        values.put(MySql.ORDER_COUNTRY, country);
        db.insert(MySql.TABLE_NAME, null, values);

        db.setTransactionSuccessful();
        db.endTransaction();
    }

    @Override
    public void delete(int orderid) {

        db.beginTransaction();

        int result = db.delete(MySql.TABLE_NAME, MySql.ORDER_ID + "=?", new String[]{String.valueOf(orderid)});

        Log.i(TAG, "delete: " + result + "  id:" + orderid);

        db.setTransactionSuccessful();
        db.endTransaction();

    }

    @Override
    public void update(int orderid) {
        db.beginTransaction();
        //update(String table, ContentValues values, String whereClause, String[] whereArgs)
        ContentValues values = new ContentValues();
        values.put(MySql.ORDER_COUNTRY, "USA" + System.currentTimeMillis());
        db.update(MySql.TABLE_NAME, values, "id=?", new String[]{String.valueOf(orderid)});

        db.setTransactionSuccessful();
        db.endTransaction();
    }

    @Override
    public Cursor select(int orderid) {
        return db.query(MySql.TABLE_NAME, new String[]{MySql._ID, MySql.ORDER_ID, MySql.ORDER_NAME, MySql.ORDER_PRICE, MySql.ORDER_COUNTRY}, "id=?", new String[]{"" + orderid + ""}, null, null, null);
    }

    @Override
    public Cursor selectAll() {
        return db.query(MySql.TABLE_NAME, new String[]{MySql._ID, MySql.ORDER_ID, MySql.ORDER_NAME, MySql.ORDER_PRICE, MySql.ORDER_COUNTRY}, null, null, null, null, null);
    }

5.性能优化
过渡绘制 开发者选项 -> 调试GPU过渡渲染
可以设置Activity的背景为null

绘制掉帧检测 开发者选择-> GPU显示配置文件 以列的形式显示于屏幕

嵌套层级过多
a.如果只有一层,考虑用LinearLayout/FrameLayout,如果多层,能用RelativeLayout一层解决,就用RelativeLayout。RelativeLayout测量两次,LinearLayout测量一次,有Weight测量两次
b.Android DeviceMonitor => Hierarchy View
去掉重复的嵌套
c.merge
d.viewstub
e.自定义ViewGroup

内存泄漏
a.Handler 用static + WeakReference,activity销毁时,调用removeCallbacksAndMessages(null)
b.static静态变量持有Activity,用WeakReference或及时置为null,如果能用Application的Context,不用Activity的
c.单例持有Activity导致内存泄漏,同上
d.非静态内部类导致内存泄漏,比如handler
e.未取消注册或回调导致内存泄漏,比如广播
f.Timer或TimerTask导致内存泄漏,要及时cancel
g.集合中的对象未清理造成内存泄漏。要及时remove或clear
h.资源未关闭或释放导致内存泄漏(IO、File、Sqlite、Cursor)
i.属性动画,比如ObjectAnimator,及时cancel
j.WebView,及时destory(),但是5.1可能还存在问题,比如WebView的callback持有Activity。因此,最好在销毁WebView之前,需要将WebView从容器移除,然后再销毁。

@Override protected void onDestroy() { super.onDestroy(); // 先从父控件中移除WebView mWebViewContainer.removeView(mWebView); mWebView.stopLoading(); mWebView.getSettings().setJavaScriptEnabled(false); mWebView.clearHistory(); mWebView.removeAllViews(); mWebView.destroy(); }

6.reactnative生命周期
https://www.race604.com/react-native-component-lifecycle/
这里写图片描述

扫描二维码关注公众号,回复: 3803366 查看本文章

7.Handler原理
http://blog.csdn.net/u012827296/article/details/51236614
http://blog.csdn.net/garyhu1/article/details/54573548
通过Looper的prepare方法创建MessageQueue
通过loop方法找到和当前线程匹配的Looper对象me
从me中取出消息队列对象mQueue
在一个死循环中,从mQueue中取出Message对象
调用每个Message对象的msg.target.dispatchMesssge方法
也就是Handler的dispatchMessage 方法
在dispatchMessage 根据Message对象的特点执行特定的方法
最终在哪里执行取决于looper,如果创建handler使用的是mainlooper则会在主线程执行,否则在创建的线程执行。
8.广播的安全性
http://blog.csdn.net/vv_bug/article/details/53292410
9.算法
http://blog.csdn.net/yuxin6866/article/details/52771739

1.快排、堆排序为首的各种排序算法
2.链表的各种操作:判断成环、判断相交、合并链表、倒数K个节点、寻找成环节点
3.二叉树、红黑树、B树定义以及时间复杂度计算方式
https://zhuanlan.zhihu.com/p/27700617
4.动态规划、贪心算法、简单的图论
http://blog.csdn.net/saltriver/article/category/6506969

10.TCP/IP
http://www.sohu.com/a/192094329_468740

11.Java知识点
http://www.importnew.com/22083.html
http://www.importnew.com/22087.html

12.ffmpeg
http://blog.csdn.net/leixiaohua1020/article/details/15811977

FFMPEG中结构体很多。最关键的结构体可以分成以下几类:
a) 解协议(http,rtsp,rtmp,mms)
AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议的类型以及状态。URLProtocol存储输入视音频使用的封装格式。每种协议都对应一个URLProtocol结构。(注意:FFMPEG中文件也被当做一种协议“file”)

b)解封装(flv,avi,rmvb,mp4)
AVFormatContext主要存储视音频封装格式中包含的信息;AVInputFormat存储输入视音频使用的封装格式。每种视音频封装格式都对应一个AVInputFormat 结构。

c)解码(h264,mpeg2,aac,mp3)
每个AVStream存储一个视频/音频流的相关数据;每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。每种解码器都对应一个AVCodec结构。

d) 存数据
视频的话,每个结构一般是存一帧;音频可能有好几帧
解码前数据:AVPacket
解码后数据:AVFrame

AVFormatContext:是包含码流参数较多的结构体,它是FFMPEG解封装(flv,mp4,rmvb,avi)功能的结构体

AVCodecContext:存储该视频/音频流使用解码方式的相关数据

AVIOContext:是FFMPEG管理输入输出数据的结构体

AVCodec:是存储编解码器信息的结构体

AVStream:是存储每一个视频/音频流信息的结构体

AVPacket:是存储压缩编码数据相关信息的结构体

AVFrame:结构体一般用于存储原始数据(即非压缩数据,例如对视频来说是YUV,RGB,对音频来说是PCM),此外还包含了一些相关的信息。比如说,解码的时候存储了宏块类型表,QP表,运动矢量表等数据。编码的时候也存储了相关的数据。因此在使用FFMPEG进行码流分析的时候,AVFrame是一个很重要的结构体。

13、描述一下JVM加载class文件的原理机制?
答:JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的,负责在运行时查找和装入类文件中的类。
当Java程序需要使用某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。
类的加载是指把类的.class文件中的数据读入到内存中,通常是创建一个字节数组读入.class文件,然后产生与所加载类对应的Class对象。
当类被加载后就进入连接阶段,这一阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引用替换为直接引用)三个步骤。
最后JVM对类进行初始化,包括:
1)如果类存在直接的父类并且这个类还没有被初始化,那么就先初始化父类;
2)如果类中存在初始化语句,就依次执行这些初始化语句。

14.正则表达式
http://www.jb51.net/tools/zhengze.html

String regex = “^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}$”;

15.面向对象的”六原则一法则”。
- 单一职责原则:一个类只做它该做的事情。(单一职责原则想表达的就是”高内聚”,写代码最终极的原则只有六个字”高内聚、低耦合”
- 开闭原则:软件实体应当对扩展开放,对修改关闭
- 依赖倒转原则:面向接口编程。(该原则说得直白和具体一些就是声明方法的参数类型、方法的返回类型、变量的引用类型时,尽可能使用抽象类型而不用具体类型,因为抽象类型可以被它的任何一个子类型所替代,请参考下面的里氏替换原则。)
- 里氏替换原则:任何时候都可以用子类型替换掉父类型。
- 接口隔离原则:接口要小而专,绝不能大而全。(接口表示能力,那么一个接口只应该描述一种能力,接口也应该是高度内聚的。
- 合成聚合复用原则:优先使用聚合或合成关系复用代码。(类与类之间简单的说有三种关系,Is-A关系、Has-A关系、Use-A关系,分别代表继承、关联和依赖。其中,关联关系根据其关联的强度又可以进一步划分为关联、聚合和合成,但说白了都是Has-A关系,合成聚合复用原则想表达的是优先考虑Has-A关系而不是Is-A关系复用代码,记住:任何时候都不要继承工具类,工具是可以拥有并可以使用的,而不是拿来继承的。)
- 迪米特法则:迪米特法则又叫最少知识原则,一个对象应当对其他对象有尽可能少的了解。(迪米特法则简单的说就是如何做到”低耦合”,门面模式和调停者模式就是对迪米特法则的践行。)

16.23种设计模式,包括:
Abstract Factory(抽象工厂模式),
Builder(建造者模式),
Factory Method(工厂方法模式),
Prototype(原始模型模式),
Singleton(单例模式);
Facade(门面模式),
Adapter(适配器模式),
Bridge(桥梁模式),
Composite(合成模式),
Decorator(装饰模式),
Flyweight(享元模式),
Proxy(代理模式);
Command(命令模式),
Interpreter(解释器模式),
Visitor(访问者模式),
Iterator(迭代子模式),
Mediator(调停者模式),
Memento(备忘录模式),
Observer(观察者模式),
State(状态模式),
Strategy(策略模式),
Template Method(模板方法模式),
Chain Of Responsibility(责任链模式)

猜你喜欢

转载自blog.csdn.net/likuan0214/article/details/79417745