Fork me on GitHub

Android之意外收获

格式化

四舍五入

  /**
     * 对double 类型数据进行四舍五入,并保留两位小数
     */
 public static double getShortDouble(double value) {
        return Math.round(value * 100) / 100.0;
    }

日志

   /**
     * 获取打印信息所在方法名,行号等信息
     */
 public static String[] getAutoJumpLogInfos() {
        String[] infos = new String[]{"", "", ""};
        StackTraceElement[] elements = Thread.currentThread().getStackTrace();
        infos[0] = elements[4].getClassName().substring(elements[4].getClassName().lastIndexOf(".") + 1);
        infos[1] = elements[4].getMethodName();
        infos[2] = "(" + elements[4].getFileName() + ":" + elements[4].getLineNumber() + ")";
        return infos;
}

关于手机

跨进程通讯(IPC)

多进程方式 内容
Intent row 1 col 2
共享文件 row 2 col 2
SharedPreference row 2 col 2
Binder的Mseeage row 2 col 2
AIDL row 2 col 2
Socket row 2 col 2

基础概念

序列化:Serializable,Parcelable接口,Binder

Serializable

实现此接口就行,给serialVersionUID赋值。serialVersionUID此值是为了校验序列化前后类的成员变量是否有改变,结构类型是否发生了改变。

Parcelable

一个类实现此接口,类的对象就可以通过Intent和Binder传递。

  1. 内容描述功能由describeContents方法
public int describeContents() {
    //默认是0;当当前对象中存在文件描述符时,返回1
    return 0;
}
  1. 序列化:writeToParcel和Parcel.writeXX()
  2. 反序列:CREATOR和Parcel.readXX()
  3. 存在序列化变量时
成员变量中存在需要序列化的对象时,在读取的是后需要使用
in.readParcelable(Thread.currentThread().getContextClassLoader());

序列化对比

  • Parcelable比较适合Android的内存序列化
  • Serializable比较适合序列化到存储设备或网络传输

Binder

Android主要用在Service中,包括AIDL和Messager(底层实现是AIDL)

  • DESCRIPTOR Binder唯一标识
  • asInterface(android.os.IBinder obj) 用于将服务端的Binder对象转换成客户端所需的AIDL接口类型的对象,转换是区分进程的,客户端和服务端在同一进程返回的就是服务端的Stub对象本身,否则返回的是封装后的Stub.proxy对象
  • asBinder 返回Binder对象
  • onTransact 运行在服务端中的Binder线程池中
  • Proxy#method()
1. 运行在客户端中,发起请求的时候,创建输入性Parcel_data对象,输出型Parcel_reply对象,返回值对象
2. 把参数写入_data中,调用transact()发起RPC请求并挂起当前线程
3. 服务端onTransact()被调用,返回结果后,当前线程继续执行
4. 从_reply中取出RPC过程的返回结果,最后返回_reply中的数据可客户端使用

相机

是否存在相机
getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);

if(hasDefualtCameraApp(MediaStore.ACTION_IMAGE_CAPTURE)){
    //是否存在相机的App,以供选择使用你当前手机的相机
}
private boolean hasDefualtCameraApp(String action){
        final PackageManager packageManager = getPackageManager();
        final Intent intent = new Intent(action);
        List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        return list.size() > 0;
}
申请权限
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

关于界面

  • 禁止截屏:设置当前界面为安全屏幕
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, 
WindowManager.LayoutParams.FLAG_SECURE);
  • 隐藏标题
//需要在setContent之前,因为对于Window属性的改变会对View的绘制树产生影响,避免View的重新绘制
requestWindowFeature(Window.FEATURE_NO_TITLE);
  • 状态栏
    //  使状态栏透明,用图片作为其背景的时候用
public static void setTranslucent(Activity activity) {
        if (activity != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    //  对Android 6.0 即以上设置状态栏icon为深色
 public static void darkStatusIcon(Activity activity) {
        if (activity != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }
 }

关于Paint

  • API
// 重置Paint。
void reset();
// 是否抗锯齿
void setAntiAlias(boolean aa);
// 设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰  
void setDither(boolean dither);
// 设置线性文本
void setLinearText(boolean linearText);
// 设置该项为true,将有助于文本在LCD屏幕上的显示效果  
void setSubpixelText(boolean subpixelText);
// 设置下划线
void setUnderlineText(boolean underlineText);
// 设置带有删除线的效果 
void setStrikeThruText(boolean strikeThruText);
// 设置伪粗体文本,设置在小字体上效果会非常差  
void setFakeBoldText(boolean fakeBoldText);
// 如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作
// 加快显示速度,本设置项依赖于dither和xfermode的设置  
void setFilterBitmap(boolean filter);
// 设置画笔风格,空心或者实心 FILL,FILL_OR_STROKE,或STROKE
// Paint.Style.STROKE 表示当前只绘制图形的轮廓,而Paint.Style.FILL表示填充图形。  
void setStyle(Style style);
// 设置颜色值
void setColor(int color);
// 设置透明图0~255,要在setColor后面设置才生效
void setAlpha(int a);   
// 设置RGB及透明度
void setARGB(int a, int r, int g, int b);  
// 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度  
void setStrokeWidth(float width);
void setStrokeMiter(float miter);
// 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷末端的图形样式
// 如圆形样式Cap.ROUND,或方形样式Cap.SQUARE  
void setStrokeCap(Cap cap);
// 设置绘制时各图形的结合方式,如平滑效果等  
void setStrokeJoin(Join join);
// 设置图像效果,使用Shader可以绘制出各种渐变效果  
Shader setShader(Shader shader);
// 设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果 
ColorFilter setColorFilter(ColorFilter filter);
// 设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果 
Xfermode setXfermode(Xfermode xfermode);
// 设置绘制路径的效果,如点画线等 
PathEffect setPathEffect(PathEffect effect);
// 设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等  
MaskFilter setMaskFilter(MaskFilter maskfilter);
// 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等  
Typeface setTypeface(Typeface typeface);
// 设置光栅化
Rasterizer setRasterizer(Rasterizer rasterizer);
// 在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
// 注意:在Android4.0以上默认开启硬件加速,有些图形的阴影无法显示。关闭View的硬件加速 view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
void setShadowLayer(float radius, float dx, float dy, int color);
// 设置文本对齐
void setTextAlign(Align align);
// 设置字体大小
void setTextSize(float textSize);
// 设置文本缩放倍数,1.0f为原始
void setTextScaleX(float scaleX);
// 设置斜体文字,skewX为倾斜弧度  
void setTextSkewX(float skewX);
  • Paint的Xfermode
 private static final Xfermode[] sModes = {
        new PorterDuffXfermode(PorterDuff.Mode.CLEAR),      // 清空所有,要闭硬件加速,否则无效
        new PorterDuffXfermode(PorterDuff.Mode.SRC),        // 显示前都图像,不显示后者
        new PorterDuffXfermode(PorterDuff.Mode.DST),        // 显示后者图像,不显示前者
        new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER),   // 后者叠于前者
        new PorterDuffXfermode(PorterDuff.Mode.DST_OVER),   // 前者叠于后者
        new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),     // 显示相交的区域,但图像为后者
        new PorterDuffXfermode(PorterDuff.Mode.DST_IN),     // 显示相交的区域,但图像为前者
        new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),    // 显示后者不重叠的图像
        new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),    // 显示前者不重叠的图像
        new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP),   // 显示前者图像,与后者重合的图像
        new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP),   // 显示后者图像,与前者重合的图像
        new PorterDuffXfermode(PorterDuff.Mode.XOR),        // 显示持有不重合的图像
        new PorterDuffXfermode(PorterDuff.Mode.DARKEN),     // 后者叠于前者上,后者与前者重叠的部份透明。要闭硬件加速,否则无效
        new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),    // 前者叠于前者,前者与后者重叠部份透明。要闭硬件加速,否则无效
        new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),   // 显示重合的图像,且颜色会合拼
        new PorterDuffXfermode(PorterDuff.Mode.SCREEN)    // 显示持有图像,重合的会变白
};

关于Intent

  • 打开浏览器
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//小米需要加这个
context.startActivity(intent);
  • 打开应用商店
跳转到应用的详情页:
Uri uri = Uri.parse("market://details?id=" + pkgName);//包名
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setPackage("com.xxx.xxx");//应用商店
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
  • 分享
public static void shareImage(Context context,String title, Uri uri) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_STREAM, uri);
        context.startActivity(Intent.createChooser(intent, title));
}

public static void shareText(Context context,String title, String text){
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.putExtra(Intent.EXTRA_SUBJECT, title);
        intent.putExtra(Intent.EXTRA_TEXT, text);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
	context.startActivity(Intent.createChooser(intent, title));
}

退出App

1. 他杀方式
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
am.killBackgroundProcesses(packageName)
2. 自杀
2.1 killProcess()
android.os.Process.killProcess(android.os.Process.myPid())
2.2 系统的方法 
System.exit()
2.3 抛出异常
使程序Force Close,不友好
2.4 栈
记录打开的Activity,退出时杀死那些Activity
2.5 发送广播
在需要结束应用时,发送一个特定的广播,每个Activity收到广播后,关闭即可。 
2.6 递归退出
使用startActivityForResult和加标志,在onActivityResult中处理,递归关闭。

多线程的启动

多线程启动有哪些方式?
1) new Thread()
2) AsyncTask
3) Handler
4) IntentService
5) ThreadPoolExecutor
posted @ 2021-06-17 17:18  KevinAt2022  阅读(86)  评论(0)    收藏  举报