小编Mis*_*ith的帖子

Java 8:Streams vs Collections的性能

我是Java 8的新手.我仍然不深入了解API,但我已经做了一个小的非正式基准测试来比较新Streams API与优秀旧Collections的性能.

测试包括过滤一个列表Integer,并为每个偶数计算平方根并将其存储在结果ListDouble.

这是代码:

    public static void main(String[] args) {
        //Calculating square root of even numbers from 1 to N       
        int min = 1;
        int max = 1000000;

        List<Integer> sourceList = new ArrayList<>();
        for (int i = min; i < max; i++) {
            sourceList.add(i);
        }

        List<Double> result = new LinkedList<>();


        //Collections approach
        long t0 = System.nanoTime();
        long elapsed = 0;
        for (Integer i : sourceList) {
            if(i % 2 == 0){
                result.add(Math.sqrt(i));
            } …
Run Code Online (Sandbox Code Playgroud)

java collections performance java-8 java-stream

126
推荐指数
4
解决办法
7万
查看次数

更新GUI:Runnables vs Messages

要从其他线程更新GUI,基本上有两种主要方法:

  1. 将java.lang.Runnable与以下任何方法一起使用:

    Activity.runOnUiThread(Runnable)
    View.post(Runnable)
    View.postDelayed(Runnable, long)
    Handler.post(Runnable)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用android.os.Message:

    Handler.sendMessage(Message) / Handler.handleMessage(Message)
    
    Run Code Online (Sandbox Code Playgroud)

您也可以使用AsyncTask,但我的问题更侧重于更新非常简单的组件的用例.让我们看看如何使用这两种方法完成:

  1. 使用Runnables:

    TextViev tv = ...;
    final String data = "hello";
    Runnable r = new Runnable() {
    
        @Override
        public void run(){
            tv.setText(data);
        }
    
    };
    //Now call Activity.runOnUiThread(r) or handler.post(r), ...
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用消息:

    Message m = handler.obtainMessage(UPDATE_TEXT_VIEW, "hello");
    handler.sendMessage(m);
    
    //Now on handler implementation:
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == UPDATE_TEXT_VIEW){
                String s = (String) msg.obj;
                tv.setText(data);
            } ... //other IFs?
        }
    
    Run Code Online (Sandbox Code Playgroud)

恕我直言,消息不是要走的路,因为:

  • 对于新的非android程序员来说并不容易理解(在构造期间处理程序挂钩到它的线程).
  • 如果消息跨越进程边界,则对象有效负载应为Parcellable.
  • 消息被重用(如果没有正确清理,则容易出错?)
  • 处理程序具有双重角色(它发送消息,但也处理它们)
  • 消息属性是公共的,但也提供getter/setter.

另一方面,Runnables遵循众所周知的命令模式,并且更加程序员友好且可读.

那么使用Messages …

user-interface android message runnable

46
推荐指数
3
解决办法
8845
查看次数

有关Google Play应用资产加密的问题

从v4.1 Jelly Bean开始,Google为Google Play引入了一项新的应用程序资产加密功能.似乎在升级包含持久性数据的应用程序时出现了一些问题,这些问题是由apk目录中的更改引起的(旧的/data/app,现在是/mnt/asec).

因此,在Google Play上发布(或更新已发布的应用)时,对于OS 2.3+,

  • 我可以禁用此选项并发布未加密的应用程序吗?
  • 问题的当前状态是什么?有解决方法吗?

除了这个问题,提供额外的防盗版保护的想法似乎没问题,但是在文档的任何地方都有一些我无法解释的额外注意事项:

  • 那些发布到替代商店或通过OTA部署的应用程序呢?他们也可以加密吗?如果没有,那么如果有人可以从其他地方下载未加密的apk并直接反编译,那么在Google Play发布中造成如此大的痛苦的重点是什么?
  • 可以通过生根电话来打败它吗?
  • 为OS 4.0+提供的apks是唯一有保护的吗?如果是这样,那么,如果有人可以将未加密的apk下载到Gingerbread手机,用adb将其拉出并以通常的方式反编译,那又有什么意义呢?
  • 假设机制有效:备份应用程序(如Titanium Backup)或使用adb的手动apk备份怎​​么样?他们还会工作吗?
  • 性能:某些应用可能具有相当大的apk大小.这种机制会妨碍性能吗?操作系统每次加载时都会解密整个apk吗?

提前致谢

更新:
修改以包含指向Google代码问题的链接.
问题34880(关闭,但有些开发者仍抱怨;状态:未来发布)
问题35962(已关闭;状态:已发布)

更新#2:由第一期中的一位开发人员链接的此博客文章的
有趣信息.同样在这里,在德国.

用户和开发人员报告说,在最近几天,使用最新版Google Play(3.7.15)安装的应用程序的问题似乎已经消失.以前安装有问题的应用程序的用户需要卸载,然后免费重新下载.根据一份报告,新版Google Play现在再次将付费应用程序保存到/ data/app,这意味着Google暂时停用了复制保护功能.谷歌没有公开评论这个问题.该错误被标记为中等优先级,状态为"FutureRelease"以进行可能的修复.

encryption android apk google-play android-4.2-jelly-bean

42
推荐指数
1
解决办法
2139
查看次数

阻止其他程序员调用-init的最佳方法

在设计类层次结构时,有时子类添加了一个新initWithSomeNewParam方法,并且希望禁用对init从超类继承的旧方法的调用.

首先,我在这里阅读了这个问题,其中提出的替代方法是覆盖init在运行时抛出异常,或覆盖并设置属性的默认值.在我的情况下,我不想提供默认值,我想清楚地表明不应该调用旧方法,而应该使用带参数的新方法.

因此运行时异常很好,但除非代码被调试,否则团队中的其他程序员无法注意到旧方法不再用于使用.

如果我是正确的,那么就没有办法将方法标记为"私有".所以,除了添加评论之外,有没有办法做到这一点?

提前致谢.

iphone cocoa-touch objective-c init

39
推荐指数
1
解决办法
5781
查看次数

JSONObject.toString:如何不转义斜杠

我需要用JSON发送日期.日期字符串应如下所示:

"2013年5月15日"

相反,JSONObject.toString逃避它如下:

"2013\/ 5\/ 15"

我知道这样做是为了允许在脚本标签内部使用json字符串,因为这个问题解释了: JSON:为什么正斜杠被转义了?

但就我而言,我并不需要它.实际上服务器返回错误.服务器没有处理这个,我无法修复服务器,所以我必须在移动客户端代码中修复它.

String.replace序列化后我可以做一个,但如果我真的想在JSON的任何其他部分包含"\ /"字符串怎么办?

有没有办法序列化JSON对象而不转义斜杠?(如果可能,不逃避任何事情)

提前致谢.

java android json

32
推荐指数
3
解决办法
4万
查看次数

GPS:NTP时间注入的工作原理

我最近知道目录gps.conf中的/system/etc/文件.似乎将NTP_SERVER值调整到更靠近通常位置的NTP服务器可以改善TTFF.

读取类中的源代码LocationProvider,似乎在启动时,从NTP服务器检索时间并在计算中"注入".每个GPS坐着的AFAIK都有一个非常准确的原子钟,星座中的每一个都与所谓的"GPS时间"同步.一旦接收器有4个或更多卫星,它(通过某种方法)解决了一个方程,其中有四个未知数:x,y,z,b; 其中(x,y,z)是接收器位置,b是接收器内部时钟和(正确)GPS时间之间的时间差.一旦修复,接收器时钟就会与正确的时间同步.(如果我错了,请纠正我).

到目前为止,我对NTP时间注入的工作方式有一些疑问:

  1. GPS时间大致为TAI(国际原子时)加上偏移量.这两次不依赖于地球自转,但UTC确实如此.鉴于NTP服务器返回UTC时间,可以从UTC时间推断GPS时间?
  2. 如何从较近的服务器检索NTP时间可以提高GPS时间近似的"质量"?
  3. 假设我们有一个初始GPS时间值(以某种方式从NTP时间推断),注入是什么?这个时间值是否正确解决方程只有x,y,z为未知数?如果是这样,那么第一个修复也只是近似,不是吗?
  4. GPS时间的高质量初始近似如何改善TTFF?是因为NTP时间质量较低,第一次修复被认为是不可接受和丢弃的?
  5. 是否有一个近似的初始位置有助于检索下一个正确的修复(比如只收听sats的子集)?

time gps android ntp

31
推荐指数
1
解决办法
3万
查看次数

如何为布局设置不同的主题

我为整个应用设置了默认主题.它在styles.xml中定义如下:

    <style name="DefaultTheme" parent="@android:style/Theme.Holo.Light">
        <!-- Customization here -->
    </style>
Run Code Online (Sandbox Code Playgroud)

我还定义了一个黑暗的主题:

    <style name="DarkTheme" parent="@android:style/Theme.Holo">
        <!-- Customization here -->
    </style>
Run Code Online (Sandbox Code Playgroud)

在清单中,它被声明为轻主题作为应用程序的主题:

    <application
    ...
    android:theme="@style/DefaultTheme" >
Run Code Online (Sandbox Code Playgroud)

现在这个工作正常,但在一个活动中,我需要为单个布局设置不同的主题.像这样的东西:

    +--------------------------------------------------+
    |         Parent Linear layout (default theme)     |
    |                                                  |
    | +------------------------------------+ +-------+ |
    | |                                    | |       | |
    | |     Left linear layout             | |       | |
    | |     (default theme)                | |       | |
    | |                                    | |       | |
    | |                                    | |       | |
    | |                                    | |    ·<----------- Right Linear …
Run Code Online (Sandbox Code Playgroud)

user-interface android themes styles android-linearlayout

31
推荐指数
3
解决办法
2万
查看次数

如何在Android Studio中使用最新的gradle版本

我刚刚注意到Gradle 发布了2.12版,根据发行说明,脚本的编译速度提高了20%.我想在Android Studio中升级到该版本.

我使用V1.5.1和设置,我选择了"使用默认gradle这个包装"选项,这意味着不是使用本地gradle这个是安装每一个项目,一个特定版本的Gradle将用于每个项目.使用的版本是build.gradle文件中定义的版本.例:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
Run Code Online (Sandbox Code Playgroud)

现在如果我改变它:

classpath 'com.android.tools.build:gradle:2.12'
Run Code Online (Sandbox Code Playgroud)

然后Android Studio找不到该版本并抛出错误.显然,AS首先尝试在本地缓存中找到二进制文件(Android Studio/gradle/m2repository),然后尝试从bintray下载它:

https://jcenter.bintray.com/com/android/tools/build/gradle/2.12/gradle-2.12.jar
Run Code Online (Sandbox Code Playgroud)

浏览已发布的版本看起来像这里的最新版本是v2.1.0-alpha1.

  • 为什么v2.12不在bintray呢?它与Android Studio不兼容吗?
  • 如果它是兼容的,有没有办法下载它并在每个项目的基础上使用本地安装?(我不想破坏版本控制中的旧项目)

android gradle bintray android-studio

27
推荐指数
2
解决办法
7万
查看次数

对列表生成函数进行延迟评估?

我现在正在阅读Graham Hutton编写的Haskell编程.

在第40页,提出了玩具素性测试:

factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]

prime :: Int -> Bool
prime n = factors n == [1,n]
Run Code Online (Sandbox Code Playgroud)

然后,作者继续解释如何

"确定一个数字不是素数不需要函数素数来产生它的所有因子,因为在惰性求值下False,只要产生一个或多个数字本身以外的任何因子,就会返回结果"

作为来自C和Java的人,我发现这令人震惊.我希望factors调用首先完成,将结果保存在堆栈中并将控制传递给调用函数.但显然这里正在执行一个非常不同的程序:列表理解必须有一个循环,factors并且prime正在检查添加到因子列表中的每个新元素的相等性检查.

这怎么可能?这对于程序的执行顺序是否更难以推理?

haskell lazy-evaluation

26
推荐指数
3
解决办法
1874
查看次数

我应该在生产代码中留下蓝牙反射黑客吗?

我正在一个需要通过蓝牙连接到打印机的项目中工作.打印机制造商声称只有具有SPP(串行端口配置文件)的Android手机才能与打印机连接.

这是我最初打开连接的方式:

        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //SPP long UUID
        BluetoothSocket socket = device.createRfcommSocketToServiceRecord(uuid);
Run Code Online (Sandbox Code Playgroud)

使用UUID是从JellyBean开始使用Android公共API打开RFCOMM连接的唯一方法.之前曾在BlackBerry和JavaME中使用SPP连接,不需要UUID,我发现这有点奇怪.UUID是关于服务发现的,即使用SDP来查询设备中存在的服务.我真的不需要发现一个发现,因为我的打印机已提前配对,我知道它支持SPP.然而,这正是BluetoothDevice.createRfcommSocketToServiceRecord方法和不安全版本所做的.这是SPP堆栈,我们可以在其中看到SDP是如何在同一层的不同协议,因此应该可以在不首先启动发现的情况下使用RFCOMM:

        -----------------------------------
        |        My Application           |
        ----------------------------------- 
        |     Serial Port Emulation       |
        |          or other API           |
        -----------------------------------
        |      RFCOMM          |    SDP   |
        -----------------------------------
        |  LMP   |   L2PCAP               |
        -----------------------------------
        |           Baseband              |
        -----------------------------------
Run Code Online (Sandbox Code Playgroud)

我开始在一些旧的HTC设备上测试我的应用程序没有问题.后来,在三星手机上测试时,有几台设备无法打开连接.根据制造商和第三方规范,这些手机据称不支持SPP配置文件(编辑:第三方规格列表SPP支持,制造商规格不够准确).抛出了IOException(Service Discovery failed),我按照这个问题中显示的方法:

在Android上使用蓝牙的服务发现失败异常

提出的解决方案是使用反射黑客,如下:

        Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
        BluetoothSocket socket = socket = (BluetoothSocket) m.invoke(device, 1);
Run Code Online (Sandbox Code Playgroud)

黑客为我工作.令人惊讶的是,这个BluetoothDevice类中的方法是公共的,但它通过@hide注释从API中删除.这是JellyBean的源代码:

        /**
         * Create an …
Run Code Online (Sandbox Code Playgroud)

reflection android bluetooth

22
推荐指数
1
解决办法
3995
查看次数