剑道子羽

剑道子羽 查看完整档案

南京编辑武汉理工大学  |  电子商务 编辑  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

剑道子羽 发布了文章 · 9月25日

handler实现精确计时

首先说下关于handler自身的误差:

如果使用handler.postDealyed(……, 1000)方式来进行每秒的计时,是不准确的,是的,有很大误差,误差的原因在于在你收到消息,到你重新发出handler.postDealyed的时间,并不是瞬间完成的,这里面有很多逻辑处理的时间,即使没有逻辑处理的时间,handler本身也是耗损性能的,所以消息并不可能按照理想的1000延迟来进行发送,这就导致了误差的累积。

代码:

时钟接口:

public interface IDigitalClock {
    /**
 * 开始计时
 */
 void start();
 /**
 * 停止
 */
 void stop();
 /**
 * 时钟复位
 */
 void reset();
 /**
 * 重启
 */
 void restart();
}

正计时时钟:

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import java.text.DecimalFormat;

public class DefaultDigitalClock implements IDigitalClock {
    private final static String TAG = "DefaultDigitalClock";
    private final static int TICK_EVENT = 0x1001;
    private Ticker mTicker;
    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            if (msg.what == TICK_EVENT) {
                long seconds = (long) msg.obj;
                String HHMMss = formatElapsedTime(seconds);
                clock.tick(seconds, HHMMss);
            }
            return false;
        }
    });
    private long startTime;
    private long elapsedSeconds;
    private long maxSeconds;
    private ClockOnMainThread clock;
    public DefaultDigitalClock(ClockOnMainThread clock) {
        this(-1, clock);
    }
    public DefaultDigitalClock(long maxSeconds, ClockOnMainThread clock) {
        this.maxSeconds = maxSeconds;
        this.clock = clock;
        this.elapsedSeconds = -1;
        this.startTime = -1;
    }
    @Override
    public void start() {
        startTime = System.currentTimeMillis();
        mTicker = new Ticker();
        long now = SystemClock.uptimeMillis();
        long next = now + (1000 - now % 1000);
        handler.postAtTime(mTicker, next);
    }
    @Override
    public void stop() {
        handler.removeMessages(TICK_EVENT);
        if (mTicker != null) {
            handler.removeCallbacks(mTicker);
        }
    }
    @Override
    public void reset() {
        elapsedSeconds = -1;
        startTime = -1;
        handler.sendMessage(newTick(0));
    }
    @Override
    public void restart() {
        stop();
        reset();
        start();
    }
    /**
     * 在每秒的整点执行
     * {@link "https://blog.csdn.net/cpcpcp123/article/details/88542113"}
     */ 
     private final class Ticker implements Runnable {
        public void run() {
            onTimeChanged();
            // 在设定秒数后结束
            if (maxSeconds > 0 && elapsedSeconds == maxSeconds) {
                stop();
                return;
            }
            long now = SystemClock.uptimeMillis();
            long next = now + (1000 - now % 1000);
            handler.postAtTime(this, next);
        }
    };
    /**
     * 计算时间变化
     */
    private void onTimeChanged() {
        if (Thread.currentThread() != Looper.getMainLooper().getThread()) {
            Log.e(TAG, "onTimeChanged() must work on main thread!");
            return;
        }
        elapsedSeconds = (System.currentTimeMillis() - startTime) / 1000;
        Log.d(TAG, String.valueOf(elapsedSeconds));
        String HHMMss = formatElapsedTime(elapsedSeconds);
        clock.tick(elapsedSeconds, HHMMss);
    }
    private Message newTick(long seconds) {
        Message msg = new Message();
        msg.what = TICK_EVENT;
        msg.obj = seconds;
        return msg;
    }
    /**
     * @see android.text.format.DateUtils#formatElapsedTime(long)
     * @param elapsedSeconds 经过的秒数
     */
    private String formatElapsedTime(long elapsedSeconds) {
        // Break the elapsed seconds into hours, minutes, and seconds.
        long hours = 0;
        long minutes = 0;
        long seconds = 0;
        if (elapsedSeconds >= 3600) {
            hours = elapsedSeconds / 3600;
            elapsedSeconds -= hours * 3600;
        }
        if (elapsedSeconds >= 60) {
            minutes = elapsedSeconds / 60;
            elapsedSeconds -= minutes * 60;
        }
        seconds = elapsedSeconds;
        String hh = new DecimalFormat("00").format(hours);
        String mm = new DecimalFormat("00").format(minutes);
        String ss = new DecimalFormat("00").format(seconds);
        return String.format("%s:%s:%s", hh, mm, ss);
    }
    
    public interface ClockOnMainThread {
        void tick(long seconds, String time);
    }
}

参考博客

查看原文

赞 0 收藏 0 评论 0

剑道子羽 发布了文章 · 9月17日

用Java模板创建你的"Hello, Harmony!"

2020年度华为开发者大会“HDC Together”于9月10日至9月12日在东莞松山湖成功举办。作为一名开发者,我有幸参加这一年一度的盛会,并且亲身体验了 Harmony OS 2.0 所开发的应用,我惊艳于这款全新的操作系统,并且坚信着未来鸿蒙必将掀起一场风暴!我希望我和对此兴趣勃勃的开发者能够有更多机会靠近漩涡的中心!

开发工具

“工欲善其事,必先利其器”。华为为了开发者能够更快地融入到鸿蒙生态中来,也为我们准备了两款 IDE,我们在华为开发者联盟官方网站就可以看到 ———
download IDE

  • DevEco Studio 2.0 是为了软件应用开发者准备的集成开发环境。风格类似于 Android Studio,也是基于 IDEA 的开源版本进行二次开发得来的。
  • HUAWEI DevEco Device Tool 则是为了硬件开发者准备的 IDE。

1.1 下载

我是一名软件应用开发者,所以我选择前者,下载地址如下:
https://developer.harmonyos.com/cn/develop/deveco-studio

下载时,要求我们注册华为账号。为什么需要注册账号呢?
我在现场问过工作人员这个问题,他们的解答如下:华为在全面开放鸿蒙系统的同时,会在华为开发者联盟内,全面支持鸿蒙应用的应用后台,渠道分发,数据统计,收益分成等等。玩法和目前基于华为开发者联盟开发手机APP差不多。

1.2 解压安装

我们下载得到了一个压缩包,例如:
devecostudio-windows-tool-2.0.8.203.zip
解压后,会得到安装程序,例如:
deveco-studio-2.0.8.203.exe
双击之后安装,基本都是点下一步就可以了。

  • 我个人在 Options 那一步骤,勾选了“创建桌面快捷方式”和“在菜单栏添加 Open Folder as Project”

1.3 安装SDK

在打开桌面上的启动图标时:
image
需要你同意一份协议,同意过后点击下一步开始安装必要的SDK,然后就可以顺利打开 IDE 了:
image

创建第一个项目

选择 Create HarmonyOS Project,进入项目模板选择页面

2.1 创建 Java 模板

image
选择一个普通的 Java 模板,然后点击 Next 进入下一步
image
点击 Finish 完成创建

2.2 修改 gradle 路径

File -> Settings...
image
打开设置页面,输入关键字 Gradle,修改 Gradle 路径为本地路径
image
设置之后可以避免每次都去 https://services.gradle.org/ 下载 zip 包

2.3 项目文件结构

image

src/main/resources 表示资源组目录,资源组目录说明如下:

资源组目录目录说明资源文件
element表示元素资源,以下每一类数据都采用相应的JSON文件来表征。element目录中的文件名称建议与下面的文件名保持一致。每个文件中只能包含同一类型的数据。
media表示媒体资源,包括图片、音频、视频等非文本格式的文件。文件名可自定义,例如:icon.png。
animation表示动画资源,采用XML文件格式。文件名可自定义,例如:zoom_in.xml。
layout表示布局资源,采用XML文件格式。文件名可自定义,例如:home_layout.xml。
graphic表示可绘制资源,采用XML文件格式。文件名可自定义,例如:notifications_dark.xml。
profile表示其他类型文件,以原始文件形式保存。文件名可自定义。

以上表格参考官方文档 :资源文件分类

本文 Demo 中将主要用到 media 文件夹和 layout 文件夹。

2.4 满天星光

image
这张图是华为开发者大会2020上,余承东 发言时的一张 PPT,我们就来把这个页面开发并展示在 TV 设备上。

2.5 新建布局

首先在 entry 模块下 src/main/resources/base 文件夹下创建 layout 文件夹:
image
接着,右击layout文件 New -> Layout Resource File
image
打开 Create Layout Resource File对话框,输入 layout_main
image
我们成功创建了一个 layout_main.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:width="match_parent"
    ohos:height="match_parent"
    ohos:orientation="vertical">
</DirectionalLayout>

Android 和 鸿蒙中的有一些差异,首先是命名空间:

  • Android:xmlns:android="http://schemas.android.com/apk/res/android"
  • Harmony:xmlns:ohos="http://schemas.huawei.com/res/ohos"

线性布局:

  • Android: LinearLayout
  • Harmony: DirectionLayout

2.6 安装远程虚拟机

我们接下来想要调试程序了,所以需要一台设备。目前鸿蒙还未支持手机应用的开发,手头上又没有能用的华为手表或者是华为电视,所以我们只能开发 Tools -> HVD Manager,弹出提示框让我们选择,我们选择 Ok
image
大家在安装时可能会和我一样遇到下载不成功的情况,我最终是通过File -> Invalidate Caches / Restart... ,并且重启计算机,最终运气好才下载成功的。
大家也可以去华为开发者论坛搜索HVD Manager寻找相关解决方案,链接我已经提供好了:
https://developer.huawei.com/consumer/cn/forum/searchlist?sk=HVD%20Manager%20%E4%B8%8B%E8%BD%BD%E5%A4%B1%E8%B4%A5

2.7 登录华为账号

打开 Tools -> HVD Manager,进入Virtual Device Manager -> 点击 Refresh 。使用远程虚拟机目前需要先登录华为账号,该华为账号还需要完成实名认证

有些浏览器会出现登录不成功的情况,建议下载最新的 Chrome 浏览器,并且在 Chrome 浏览器搜索栏输入 chrome://settings/ 打开设置,再向下翻到 默认浏览器 一栏,设置 Chrome 浏览器为默认浏览器。

image

2.8 第一次运行

打开虚拟设备,这个虚拟设备是有限制时间的,默认1h
image
接着在这台虚拟设备上运行我们的程序
image
这样我们就确定我们的项目是一个可运行的项目,接着就可以开始后续的开发了!

功能实现

3.1 引入图片

image
这是我在网上找的一张星空图,然后把它放入 entry/src/resources/base/media 文件夹:
image

图片资源访问方式:

  • 图片在 xml 的中访问方式 $media:galaxy ,类似于 Android 中的 @drawable/galaxy
  • 图片在 Java 中的访问方式 ResourceTable.Media_galaxy, 类似于 Android 中的 R.drawable.galaxy

3.2 布局代码

<?xml version="1.0" encoding="utf-8"?>
<DependentLayout xmlns:ohos="http://schemas.huawei.com/res/ohos"
                 ohos:width="match_parent"
                 ohos:height="match_parent"
                 ohos:orientation="vertical"
                 ohos:background_element="$media:galaxy">

    <DirectionalLayout
            ohos:center_in_parent="true"
            ohos:width="match_parent"
            ohos:height="match_content"
            ohos:orientation="vertical">

        <Text
                ohos:width="match_parent"
                ohos:height="match_content"
                ohos:text_alignment="center"
                ohos:text_size="24fp"
                ohos:text_color="#ffffff"
                ohos:text="没有人能熄灭满天星光"/>

        <Text
                ohos:top_margin="8vp"
                ohos:width="match_parent"
                ohos:height="match_content"
                ohos:text_alignment="center"
                ohos:text_size="24fp"
                ohos:text_color="#ffffff"
                ohos:text="每一位开发者,都是华为要汇聚的星星之火"/>
    </DirectionalLayout>

</DependentLayout>

3.3 布局解析图

运行结果:
image

布局解析:
image

  • DependentLayout 相当于Android RelativeLayout
  • DirectionLayout 相当于Android LinearLayout
  • Text 相当于Android TextView
查看原文

赞 4 收藏 0 评论 0

剑道子羽 关注了专栏 · 7月2日

SegmentFault 行业快讯

第一时间为开发者提供行业相关的实时热点资讯

关注 25224

剑道子羽 关注了专栏 · 7月2日

阿里技术

阿里巴巴官方技术号,关于阿里巴巴经济体的技术创新、实战经验、技术人的成长心得均呈现于此。

关注 1698

剑道子羽 关注了用户 · 7月2日

美团技术团队 @meituanjishutuandui

一个只分享有价值技术干货的微信公众号

美团技术团队会定期推送来自一线的实践技术文章,涵盖前端(Web、iOS和Android)、后台、大数据、AI/算法、测试、运维等技术领域。 在这里,与8000多业界一流工程师交流切磋。

关注 4785

剑道子羽 关注了用户 · 7月2日

京东设计中心JDC @jingdongshejizhongxin

致力为京东零售消费者提供完美的购物体验。以京东零售体验设计为核心,为京东集团各业务条线提供设计支持, 包括线上基础产品体验设计、营销活动体验设计、品牌创意设计、新媒体传播设计、内外部系统产品设计、企业文 化设计传播以及体验创新研究等;部门专业领域涉及用户研究、交互设计、视觉设计以及前端开发。成员分布于北 京、深圳、上海。

关注 974

剑道子羽 关注了专栏 · 7月2日

CodeGuide | 程序员编码指南

开源仓库:https://github.com/fuzhengwei/CodeGuide/wiki | 作者小傅哥多年从事一线互联网Java开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果能为您提供帮助,请给予支持(关注、点赞、分享)!

关注 5238

剑道子羽 关注了标签 · 7月2日

java

Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaSE, JavaEE, JavaME)的总称。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

Java编程语言的风格十分接近 C++ 语言。继承了 C++ 语言面向对象技术的核心,Java舍弃了 C++ 语言中容易引起错误的指針,改以引用取代,同时卸载原 C++ 与原来运算符重载,也卸载多重继承特性,改用接口取代,增加垃圾回收器功能。在 Java SE 1.5 版本中引入了泛型编程、类型安全的枚举、不定长参数和自动装/拆箱特性。太阳微系统对 Java 语言的解释是:“Java编程语言是个简单、面向对象、分布式、解释性、健壮、安全与系统无关、可移植、高性能、多线程和动态的语言”。

版本历史

重要版本号版本代号发布日期
JDK 1.01996 年 1 月 23 日
JDK 1.11997 年 2 月 19 日
J2SE 1.2Playground1998 年 12 月 8 日
J2SE 1.3Kestrel2000 年 5 月 8 日
J2SE 1.4Merlin2002 年 2 月 6 日
J2SE 5.0 (1.5.0)Tiger2004 年 9 月 30 日
Java SE 6Mustang2006 年 11 月 11 日
Java SE 7Dolphin2011 年 7 月 28 日
Java SE 8JSR 3372014 年 3 月 18 日
最新发布的稳定版本:
Java Standard Edition 8 Update 11 (1.8.0_11) - (July 15, 2014)
Java Standard Edition 7 Update 65 (1.7.0_65) - (July 15, 2014)

更详细的版本更新查看 J2SE Code NamesJava version history 维基页面

新手帮助

不知道如何开始写你的第一个 Java 程序?查看 Oracle 的 Java 上手文档

在你遇到问题提问之前,可以先在站内搜索一下关键词,看是否已经存在你想提问的内容。

命名规范

Java 程序应遵循以下的 命名规则,以增加可读性,同时降低偶然误差的概率。遵循这些命名规范,可以让别人更容易理解你的代码。

  • 类型名(类,接口,枚举等)应以大写字母开始,同时大写化后续每个单词的首字母。例如:StringThreadLocaland NullPointerException。这就是著名的帕斯卡命名法。
  • 方法名 应该是驼峰式,即以小写字母开头,同时大写化后续每个单词的首字母。例如:indexOfprintStackTraceinterrupt
  • 字段名 同样是驼峰式,和方法名一样。
  • 常量表达式的名称static final 不可变对象)应该全大写,同时用下划线分隔每个单词。例如:YELLOWDO_NOTHING_ON_CLOSE。这个规范也适用于一个枚举类的值。然而,static final 引用的非不可变对象应该是驼峰式。

Hello World

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

编译并调用:

javac -d . HelloWorld.java
java -cp . HelloWorld

Java 的源代码会被编译成可被 Java 命令执行的中间形式(用于 Java 虚拟机的字节代码指令)。

可用的 IDE

学习资源

常见的问题

下面是一些 SegmentFault 上在 Java 方面经常被人问到的问题:

(待补充)

关注 105070

剑道子羽 关注了标签 · 7月2日

javascript

JavaScript 是一门弱类型的动态脚本语言,支持多种编程范式,包括面向对象和函数式编程,被广泛用于 Web 开发。

一般来说,完整的JavaScript包括以下几个部分:

  • ECMAScript,描述了该语言的语法和基本对象
  • 文档对象模型(DOM),描述处理网页内容的方法和接口
  • 浏览器对象模型(BOM),描述与浏览器进行交互的方法和接口

它的基本特点如下:

  • 是一种解释性脚本语言(代码不进行预编译)。
  • 主要用来向HTML页面添加交互行为。
  • 可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离。

JavaScript常用来完成以下任务:

  • 嵌入动态文本于HTML页面
  • 对浏览器事件作出响应
  • 读写HTML元素
  • 在数据被提交到服务器之前验证数据
  • 检测访客的浏览器信息

《 Javascript 优点在整个语言中占多大比例?

关注 134654

剑道子羽 关注了标签 · 7月2日

程序员

一种近几十年来出现的新物种,是工业革命的产物。英文(Programmer Monkey)是一种非常特殊的、可以从事程序开发、维护的动物。一般分为程序设计猿和程序编码猿,但两者的界限并不非常清楚,都可以进行开发、维护工作,特别是在中国,而且最重要的一点,二者都是一种非常悲剧的存在。

国外的程序员节

国外的程序员节,(英语:Programmer Day,俄语:День программи́ста)是一个俄罗斯官方节日,日期是每年的第 256(0x100) 天,也就是平年的 9 月 13 日和闰年的 9 月 12 日,选择 256 是因为它是 2 的 8 次方,比 365 少的 2 的最大幂。

1024程序员节,中国程序员节

1024是2的十次方,二进制计数的基本计量单位之一。程序员(英文Programmer)是从事程序开发、维护的专业人员。程序员就像是一个个1024,以最低调、踏实、核心的功能模块搭建起这个科技世界。1GB=1024M,而1GB与1级谐音,也有一级棒的意思。

从2012年,SegmentFault 创办开始我们就从网络上引导社区的开发者,发展成中国程序员的节日 :) 计划以后每年10月24日定义为程序员节。以一个节日的形式,向通过Coding 改变世界,也以实际行动在浮躁的世界里,固执地坚持自己对于知识、技术和创新追求的程序员们表示致敬。并于之后的最为临近的周末为程序员们举行了一个盛大的狂欢派对。

2015的10月24日,我们SegmentFault 也在5个城市同时举办黑客马拉松这个特殊的形式,聚集开发者开一个编程大爬梯。

特别推荐:

【SF 黑客马拉松】:http://segmentfault.com/hacka...
【1024程序员闯关秀】小游戏,欢迎来挑战 http://segmentfault.com/game/

  • SF 开发者交流群:206236214
  • 黑客马拉松交流群:280915731
  • 开源硬件交流群:372308136
  • Android 开发者交流群:207895295
  • iOS 开发者交流群:372279630
  • 前端开发者群:174851511

欢迎开发者加入~

交流群信息


程序员相关问题集锦:

  1. 《程序员如何选择自己的第二语言》
  2. 《如何成为一名专业的程序员?》
  3. 《如何用各种编程语言书写hello world》
  4. 《程序员们最常说的谎话是什么?》
  5. 《怎么加入一个开源项目?》
  6. 《是要精于单挑,还是要善于合作?》
  7. 《来秀一下你屎一般的代码...》
  8. 《如何区分 IT 青年的“普通/文艺/二逼”属性?》
  9. 程序员必读书籍有哪些?
  10. 你经常访问的技术社区或者技术博客(IT类)有哪些?
  11. 如何一行代码弄崩你的程序?我先来一发
  12. 编程基础指的是什么?
  13. 后端零起步:学哪一种比较好?
  14. 大家都用什么键盘写代码的?

爱因斯坦

程序猿崛起

关注 110528

认证与成就

  • 获得 4 次点赞
  • 获得 1 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 1 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 7月2日
个人主页被 232 人浏览