想学画画的羊


  • Tags

  • Categories

  • Archives

Dagger2使用小结

Posted on 2019-02-12 | In android | | Visitors:

配置 dagger2 到工程

  • 根目录下的build.gradle

    1
    2
    3
    4
    5
    buildscript {
    dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
    }
  • app下的build.gradle

    1
    2
    3
    4
    5
    6
    apply plugin: 'com.neenbedankt.android-apt'
    dependencies {
    apt 'com.google.dagger:dagger-compiler:2.4'
    compile 'com.google.dagger:dagger:2.4'
    provided 'org.glassfish:javax.annotation:10.0-b28' // @Inject的包
    }
Read more »

常用功能在Android N上的变化

Posted on 2019-02-12 | In android | | Visitors:

主要记录对code影响比较大的行为变化

工程瘦身:后台优化

为了优化内存使用和电量的消耗,Android N去掉了三个隐式的广播。这个改变对用户来说绝对一大利好,因为后台注册这些广播的app在后台会经常被拉起,自然而然会影响到设备性能进而影响用户体验(很不幸,对开发者来讲,又有一些trick被限制了)。比如CONNECTIVITY_ACTION,在N之前的系统中,注册该广播的app在网络连接有变动时都会收到系统发出的广播,这样主进程被kill的app就可以复活了。此外还有ACTION_NEW_PICTURE
和 ACTION_NEW_VIDEO。
对于这三个广播,Android N具体做了如下的优化:

Read more »

打包aar和jar文件

Posted on 2019-02-12 | In android | | Visitors:

Library不包含远程库的情况

如果不包含远程库,那么项目在build一次后会在 Library_Directory/build/intermediates/bundles/release/ 下生成class文件和资源文件。所以可以通过对这些文件的压缩打包来获得jar包或者aar文件

Read more »

打开第三方App的方法

Posted on 2019-02-12 | In android | | Visitors:

打开其他apk大体分为两种方式,一个是通过 包名去打开,一种是通过URI。但是由于URI需要第三方App设置了 URI协议,要通过URI打开必须知道第三方设置的URI是什么,局限还是比较大的。所以一般都是用URI去打开系统App,比如app商店(market://), 电话(tel://)等。

####包名打开第三方App:

  1. 最简单的方法

    1
    2
    Intent intent = new Intent("包名");
    this.startActivity(intent);
  2. 指定打开在AndroidManifest.xml中声明为MAIN的Activity,并根据Task affinity判断是不是在一个新activity task栈中push准备打开的app

    1
    2
    3
    4
    5
    6
    Intent intent = new Intent();
    ComponentName comp = new ComponentName("com.linxcool","com.linxcool.PlaneActivity");
    intent.setComponent(comp);
    intent.setAction("android.intent.action.MAIN"); //参考 http://craftsman001.blog.51cto.com/9187002/1685847
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //参考 http://blog.csdn.net/berber78/article/details/7278408
    startActivity(intent);
  3. 打开App前先检查是否安装

    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
    public boolean isAppInstalled(Context context, String packageName) {
    try {
    context.getPackageManager().getPackageInfo(packageName, 0);
    return true;
    } catch (NameNotFoundException e) {
    return false;
    }
    }

    // 打开app store 对应app详情页去进行下载
    public void goToMarket() {
    Uri uri = Uri.parse("market://details?id=" + packageName);
    Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
    try {
    context.startActivity(goToMarket);
    } catch (ActivityNotFoundException e) {
    }
    }

    public void openApp(String packageName) {
    if (isAppInstalled(this, packageName)) {
    this.startActivity(packageName);
    } else {
    goToMarket(packageName);
    }
    }

URI打开App

用来打开第三方App不常用,除非都是一个开发者,可以知道被打开的App配置的URI才能正确打开,所以URI的方式还是多用来打开系统App,打开代码都一样,只是URI不同

  • 代码

    1
    2
    3
    4
    5
    6
    7
    8
    public void openAppByURI(String uri) {
    Uri uri = Uri.parse(uri);
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    try {
    context.startActivity(intent);
    } catch (ActivityNotFoundException e) {
    }
    }
  • 常用系统URI
    1.显示地图: URI:”geo:38.899533,-77.036476”

  1. 路径规划: URI:””http://maps.google.com/maps?f=dsaddr=startLat%20startLng&daddr=endLat%20endLng&hl=en""
  2. 播放多媒体

    1
    2
    3
    4
    5
    6
    7
    Intent it = new Intent(Intent.ACTION_VIEW);
    Uri uri =Uri.parse("file:///sdcard/song.mp3");
    it.setDataAndType(uri,"audio/mp3"); // 指定多媒体类型才知道用什么打开
    startActivity(it);
    Uri uri =Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"1"); //一般是存在内部存储空间的音频文件,通常不用这个。
    Intent it = new Intent(Intent.ACTION_VIEW,uri);
    startActivity(it);
  3. 打开照相机

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    //1
    Intent intent = new Intent("android.media.action.STILL_IMAGE_CAMERA"); //调用照相机
    startActivity(intent);
    //2
    Intent i = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
    this.sendBroadcast(i);
    //3
    long dateTaken = System.currentTimeMillis();
    String name = createName(dateTaken) + ".jpg";
    fileName = folder + name;
    ContentValues values = new ContentValues();
    values.put(Images.Media.TITLE, fileName);
    values.put("_data", fileName);
    values.put(Images.Media.PICASA_ID, fileName);
    values.put(Images.Media.DISPLAY_NAME, fileName);
    values.put(Images.Media.DESCRIPTION, fileName);
    values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, fileName);
    Uri photoUri = getContentResolver().insert(
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,values);

    Intent inttPhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    inttPhoto.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
    startActivityForResult(inttPhoto, 10);

几种常见的设计模式

Posted on 2019-02-12 | In android | | Visitors:

###单例模式
饥汉模式——饱汉模式——双重锁模式(多线程)

####饥汉模式:加载的就创建parm

1
2
3
4
5
6
class A {
static Object parm = new Object();
public static Object instance() {
return parm;
}
}

Read more »

启动页的实现

Posted on 2019-02-12 | In android | | Visitors:

1. 静态启动页

1. 用Theme设置启动页

先说最简单的一种启动页的实现方式,在AndroidManifest.xml 的第一个Activity添加一个theme,在theme中设置windowBackground*就行,可以用一张图片(不支持gif)或者一种颜色。

values/styles.xml

1
2
3
4
5
<resources>
<style name="Theme.StartPage" parent="Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen">
<item name="android:windowBackground">@drawable/splash_image</item>
</style>
</resources>

AndroidManifest.xml

1
2
3
4
5
<activity
android:name=".SplashActivity"
android:launchMode="singleTop"
android:theme="@style/Theme.StartPage"
>

这样设置启动页是无法避免刚打开app时出现的黑屏或者白屏,启动页的意义不大。

Read more »

react native 的flex布局

Posted on 2019-02-09 | In react native | | Visitors:

react native 的flex布局

flex=1和flex=0(默认)有什么区别?

react native是基于flex容器进行设计的,当对component没有显式地设置flex的时候,flex=0,此时的component类似与android中的’content-wrap’,它的长和宽由自身的style来设置,或者在style没有设置长宽的时候由子组件的长宽来设置(包裹子组件)。

当flex=1且没有同级的组件,那它就会占满父组件或占满屏幕。flex>0时,它就是对一个组件大小权重的设置。

Read more »

Deeplink 被js和native同时监听并正确处理

Posted on 2019-02-09 | In react native | | Visitors:

Deeplink 被js和native同时监听并正确处理

看标题觉得不明觉厉,因为RN的js部分都在一个MainActivity,其他native页面时另外的activity;而一个Deeplink在一个app中被两个Activity监听到,并且可以各自处理,这基本是不可能的事情。因为在浏览器打开一个 deeplink 的app时如果有2个Activity注册了去监听,那么会让你去选择一个来打开这个deeplink,被选的那个会被唤醒去处理link。

所以要做到这一点,需要一个中间层的actvity去监听deeplink,然后根据在后台时时那个Activity进行跳转。当然,没有在后台的话,就更加情况看最后需要显示的页面是js的还是native的来进行跳转。大概思路很简单,但实际实现会遇到很多问题。

Read more »

react所在Activity与其他Activity之间的跳转

Posted on 2019-02-09 | In react native | | Visitors:

RN可看作是一个特殊的Activity,它的View由React类型的标签来表达,但大部分React标签使用的还是原生的Native控件,这大概就是他为啥叫React Native的原因吧。

既然RN可以看作是一个Activity,那么Android中Activity之间的跳转通常用intent来实现。

Read more »

基于react的通知组件

Posted on 2019-02-09 | In react native | | Visitors:

为什么要做一个不用原生控件的通知

目前React Native的通知控件都会涉及使用到原生控件,但是需要知道IOS的通知行为非常麻烦,需要客户端发送通知给apple server,再由apple server发送通知给客户端显示在通知栏。这个行为会有一些不确定因素:网络不稳定,通知延时等。

所以,如果降低通知组件的要求:

  1. 不要求app在退出前台后仍然能够收到通知。
  2. 不需要通知显示在通知栏

但这个自定义通知组件仍然需要遵循其他通知应该有的特性:

  1. 出现通知时,用户仍然可以对app进行操作
  2. 用户可以手动去除通知
  3. 用户可以通过点击通知,触发一些行为
  4. 可以同时收到多条通知,并且用户可以分别触发对应的行为
    看到第一点要求就果断抛弃Modal,但看了react native官方提供的组件,没有能满足这个要求组件。
    Read more »
123

Thomas.Lee

主要涉及android,react native和部分java知识的博客

24 posts
2 categories
20 tags
GitHub
© 2019 Thomas.Lee
本站总访问量 次 | 有人看过我的博客啦