安卓TV开发遇到的那些坑

2023-05-16

	最近公司需要开发一个TV的luancher,就是那种纯物理按键的遥控,没有触摸屏,现在说说我踩得那些坑。(其实布局和代码逻辑和正常的安卓应用差不多)
	1.焦点   焦点   焦点,重要的事情说三遍,安卓TV由于没有触摸屏所以需要手动设置可以获取焦点的控件。
	2.设置获取到状态也就是常用的select。
	3.各种事件冲突。
	4.按键事件 通过重写onKeyDown(),onKeyUp()方法中监听keyCode的值,来判断用户按下的是哪个键,比如OK键  其他特殊的键值,上下左右键的话,系统会自动处理的。
其实遇到最烦的也就是焦点了,下面列举一下遇到的几件坑爹事情。

1.viewpager嵌套fragment中嵌套gridview,onkeyDown事件中的OK键的键值回调不出来,经过一系列的排查发现是系统的gridview中把以下四个键值给处理掉了。

case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_SPACE:
case KeyEvent.KEYCODE_NUMPAD_ENTER:

跟着源码查看:GridView.java中查看onKeyDown()方法:

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return commonKey(keyCode, 1, event);
   }

继续往下跟commonKey()方法:

    private boolean commonKey(int keyCode, int count, KeyEvent event) {
        if (mAdapter == null) {
            return false;
        }

        if (mDataChanged) {
            layoutChildren();
        }

        boolean handled = false;
        int action = event.getAction();
        if (KeyEvent.isConfirmKey(keyCode)
                && event.hasNoModifiers() && action != KeyEvent.ACTION_UP) {
            handled = resurrectSelectionIfNeeded();
            if (!handled && event.getRepeatCount() == 0 && getChildCount() > 0) {
                keyPressed();
                handled = true;
            }
        }

        if (!handled && action != KeyEvent.ACTION_UP) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    if (event.hasNoModifiers()) {
                        handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_LEFT);
                    }
                    break;

                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    if (event.hasNoModifiers()) {
                        handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_RIGHT);
                    }
                    break;

                case KeyEvent.KEYCODE_DPAD_UP:
                    if (event.hasNoModifiers()) {
                        handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_UP);
                    } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
                        handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_UP);
                    }
                    break;

                case KeyEvent.KEYCODE_DPAD_DOWN:
                    if (event.hasNoModifiers()) {
                        handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_DOWN);
                    } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
                        handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_DOWN);
                    }
                    break;

                case KeyEvent.KEYCODE_PAGE_UP:
                    if (event.hasNoModifiers()) {
                        handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_UP);
                    } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
                        handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_UP);
                    }
                    break;

                case KeyEvent.KEYCODE_PAGE_DOWN:
                    if (event.hasNoModifiers()) {
                        handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_DOWN);
                    } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
                        handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_DOWN);
                    }
                    break;

                case KeyEvent.KEYCODE_MOVE_HOME:
                    if (event.hasNoModifiers()) {
                        handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_UP);
                    }
                    break;

                case KeyEvent.KEYCODE_MOVE_END:
                    if (event.hasNoModifiers()) {
                        handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_DOWN);
                    }
                    break;

                case KeyEvent.KEYCODE_TAB:
                    // TODO: Sometimes it is useful to be able to TAB through the items in
                    //     a GridView sequentially.  Unfortunately this can create an
                    //     asymmetry in TAB navigation order unless the list selection
                    //     always reverts to the top or bottom when receiving TAB focus from
                    //     another widget.
                    if (event.hasNoModifiers()) {
                        handled = resurrectSelectionIfNeeded()
                                || sequenceScroll(FOCUS_FORWARD);
                    } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
                        handled = resurrectSelectionIfNeeded()
                                || sequenceScroll(FOCUS_BACKWARD);
                    }
                    break;
            }
        }

        if (handled) {
            return true;
        }

        if (sendToTextFilter(keyCode, count, event)) {
            return true;
        }

        switch (action) {
            case KeyEvent.ACTION_DOWN:
                return super.onKeyDown(keyCode, event);
            case KeyEvent.ACTION_UP:
                return super.onKeyUp(keyCode, event);
            case KeyEvent.ACTION_MULTIPLE:
                return super.onKeyMultiple(keyCode, count, event);
            default:
                return false;
        }
    }

往下跟可以看到KeyEvent.isConfirmKey()方法:

    @UnsupportedAppUsage
    public static final boolean isConfirmKey(int keyCode) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
            case KeyEvent.KEYCODE_ENTER:
            case KeyEvent.KEYCODE_SPACE:
            case KeyEvent.KEYCODE_NUMPAD_ENTER:
                return true;
            default:
                return false;
        }
    }

这里把以上4个键值给消费掉了

所以就会出现之前说的那种情况。

解决方案,重写自己的GridView继承自系统的GridView,然后重写对应方法:

public class CustomGridView extends GridView {
    public CustomGridView(Context context) {
        super(context);
    }

    public CustomGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomGridView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
            case KeyEvent.KEYCODE_ENTER:
            case KeyEvent.KEYCODE_SPACE:
            case KeyEvent.KEYCODE_NUMPAD_ENTER:
                return false;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
            case KeyEvent.KEYCODE_ENTER:
            case KeyEvent.KEYCODE_SPACE:
            case KeyEvent.KEYCODE_NUMPAD_ENTER:
                return false;}
        return super.onKeyMultiple(keyCode, repeatCount, event);
    }
}

使用以上自定义的GridView就能解决gridview中获取不到OK键的监听。

2.ScrollView中的子view获取不到焦点。因为不是触摸屏,所以需要获取焦点的view在xml中设置android:focusable="true"属性。还有个很重要的属性,也是平时触摸屏基本上用不到的属性android:descendantFocusability="afterDescendants"百度一下这个属性的3种值代表什么意思。

<ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:descendantFocusability="afterDescendants"
            android:scrollbars="none">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <LinearLayout
                    android:id="@+id/ll_ly"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/selector1"
                    android:focusable="true"
                    android:onClick="@{activity::onClick}"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="@dimen/x19"
                        android:layout_height="@dimen/x19"
                        android:layout_gravity="center_vertical"
                        android:layout_marginLeft="@dimen/x4"
                        android:src="@mipmap/icon_ly" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/x24"
                        android:layout_marginLeft="@dimen/x3"
                        android:gravity="center_vertical"
                        android:text="蓝牙"
                        android:textColor="#FFFFFF"
                        android:textSize="@dimen/x11" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/ll_pmxm"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/selector1"
                    android:focusable="true"
                    android:onClick="@{activity::onClick}"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="@dimen/x19"
                        android:layout_height="@dimen/x19"
                        android:layout_gravity="center_vertical"
                        android:layout_marginLeft="@dimen/x4"
                        android:src="@mipmap/icon_pmxm" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/x24"
                        android:layout_marginLeft="@dimen/x3"
                        android:gravity="center_vertical"
                        android:text="屏幕休眠"
                        android:textColor="#FFFFFF"
                        android:textSize="@dimen/x11" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/ll_ld"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/selector1"
                    android:focusable="true"
                    android:onClick="@{activity::onClick}"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="@dimen/x19"
                        android:layout_height="@dimen/x19"
                        android:layout_gravity="center_vertical"
                        android:layout_marginLeft="@dimen/x4"
                        android:src="@mipmap/icon_ld" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/x24"
                        android:layout_marginLeft="@dimen/x3"
                        android:gravity="center_vertical"
                        android:text="亮度"
                        android:textColor="#FFFFFF"
                        android:textSize="@dimen/x11" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/ll_cckj"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/selector1"
                    android:focusable="true"
                    android:onClick="@{activity::onClick}"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="@dimen/x19"
                        android:layout_height="@dimen/x19"
                        android:layout_gravity="center_vertical"
                        android:layout_marginLeft="@dimen/x4"
                        android:src="@mipmap/icon_cckj" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/x24"
                        android:layout_marginLeft="@dimen/x3"
                        android:gravity="center_vertical"
                        android:text="存储空间"
                        android:textColor="#FFFFFF"
                        android:textSize="@dimen/x11" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/ll_rq"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/selector1"
                    android:focusable="true"
                    android:onClick="@{activity::onClick}"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="@dimen/x19"
                        android:layout_height="@dimen/x19"
                        android:layout_gravity="center_vertical"
                        android:layout_marginLeft="@dimen/x4"
                        android:src="@mipmap/icon_rq" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/x24"
                        android:layout_marginLeft="@dimen/x3"
                        android:gravity="center_vertical"
                        android:text="日期"
                        android:textColor="#FFFFFF"
                        android:textSize="@dimen/x11" />
                </LinearLayout>

                <LinearLayout
                    android:id="@+id/ll_gybj"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/selector1"
                    android:focusable="true"
                    android:onClick="@{activity::onClick}"
                    android:orientation="horizontal">

                    <ImageView
                        android:layout_width="@dimen/x19"
                        android:layout_height="@dimen/x19"
                        android:layout_gravity="center_vertical"
                        android:layout_marginLeft="@dimen/x4"
                        android:src="@mipmap/icon_gybj" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="@dimen/x24"
                        android:layout_marginLeft="@dimen/x3"
                        android:gravity="center_vertical"
                        android:text="关于本机"
                        android:textColor="#FFFFFF"
                        android:textSize="@dimen/x11" />
                </LinearLayout>
            </LinearLayout>
        </ScrollView>

3.获取到焦点和没获取到焦点时显示的背景色不一样,这个功能在触摸屏中也经常用到的select就出来了。

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/black" android:state_focused="false" />
    <item android:drawable="@color/white1" android:state_focused="true" />
</selector>

4.RecyclerView中的item获取不到焦点的问题,或者当RecyclerView滚动时,子item的焦点就丢失了。

4.1先重写LinearLayoutManager:

public class FocusLinearLayoutManager extends LinearLayoutManager {
    public FocusLinearLayoutManager(Context context) {
        super(context);
    }

    public FocusLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public FocusLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }


    @Override
    public View onInterceptFocusSearch(View focused, int direction) {
        int count = getItemCount();//获取item的总数
        int fromPos = getPosition(focused);//当前焦点的位置
        int lastVisibleItemPos = findLastVisibleItemPosition();//最新的已显示的Item的位置
        switch (direction) {//根据按键逻辑控制position
            case View.FOCUS_UP:
                fromPos--;
                break;
            case View.FOCUS_DOWN:
                fromPos++;
                break;
        }

        Log.i("dz", "onInterceptFocusSearch , fromPos = " + fromPos + " , count = " + count+" , lastVisibleItemPos = "+lastVisibleItemPos);
        if(fromPos < 0 || fromPos >= count ) {
            //如果下一个位置<0,或者超出item的总数,则返回当前的View,即焦点不动
            if (fromPos < 0) {
                return super.onInterceptFocusSearch(focused, direction);
            }
            return focused;
        } else {
            //如果下一个位置大于最新的已显示的item,即下一个位置的View没有显示,则滑动到那个位置,让他显示,就可以获取焦点了
            if (fromPos > lastVisibleItemPos) {
                scrollToPosition(fromPos);
            }
        }
        return super.onInterceptFocusSearch(focused, direction);
    }
}

4.2 Item的根布局中添加android:focusable="true"属性和android:background="@drawable/selector1"
4.3 使用FocusLinearLayoutManager :

RecyclerView.setLayoutManager(new FocusLinearLayoutManager(this, FocusLinearLayoutManager.VERTICAL, false));

这样就解决的之前说的问题。遇到以上的坑 记录分享一下,避免再次踩坑。(总而言之,没有想象中的那么难,系统会处理很多按键的事件,就是焦点和特殊键值需要处理一下)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

安卓TV开发遇到的那些坑 的相关文章

  • 计算机组成原理中指令的四个工作周期

    文章目录 执行过程取指周期带有间址寻址的指令周期带有中断的指令周期 间指周期执行周期中断周期 执行过程 执行过程 xff1a 在取址周期后 xff0c 需要判断是否有间址周期 xff0c 如果没有就进入到了执行周期 xff0c 在执行周期过
  • Uncaught TypeError: $(...).modal is not a function

    项目场景 xff1a ssm框架配合bootstrap和AJAX xff0c 点击按钮弹出模态框 问题描述 xff1a Uncaught TypeError modal is not a function 原因分析 xff1a 没有引入bo
  • Lock锁及获取锁的四种方法

    为什么使用LOCK xff1f LOCK锁LOCK锁的上锁与解锁 为什么使用LOCK xff1f 传统的Synchronized锁有非常多的缺点 xff1a 锁的唤醒和阻塞代价较高 xff0c 线程的阻塞和唤醒 xff0c 操作系统需要在用
  • Chrome浏览器无法安装插件的解决办法

    国内不翻墙情况下 xff0c 无法正常登录谷歌账户 无法访问谷歌应用商店 xff0c 无法同步个人数据和安装使用各类插件 本文解决方法 xff1a 开发模式安装 步骤 xff1a 1 将xxx crx插件的扩展名改成 zip或者 rar并解
  • java8的ConcurrentHashMap为何放弃分段锁,为什么要使用CAS+Synchronized取代Segment+ReentrantLock

    原文地址 xff1a https cloud tencent com developer article 1509556 今天突然被一个同事问到java8为何放弃分段锁 xff0c 于是花了点时间针对这个问题进行了小小的总结 jdk1 7分
  • 8-17小记

    Comparator比较器的使用 435 无重叠区间 力扣 xff08 LeetCode xff09 leetcode cn com 给定一个区间的集合 xff0c 找到需要移除区间的最小数量 xff0c 使剩余区间互不重叠 注意 可以认为
  • Java关键字小记

    Static静态内部类静态变量和方法导包静态代码块 final用来修饰数据用来修饰方法参数修饰方法修饰类 abstractabstract类abstract方法 extendsthrow和throwsvolatile 本篇是Java关键字的
  • Java 通过反射获取方法与变量

    0 反射技术 反射技术是Java生态中的重要内容 xff0c 在Spring以及其他框架中得到了广泛的应用 有了反射技术 xff0c 我们可以在程序运行的过程中 xff1a 构建任意一个类的对象 xff0c 了解任意一个对象所属的类 xff
  • 分享一个免费版本库可以建私库

    别的不多说 目前这个行业小团队比较多 xff0c 想要版本库的话 看下面 反正我个人一直在用 所以就推荐给你们 我不介绍github xff0c 和gitorious 因为github在私人库的时候是收费的 而最早的gitorious是没办
  • ibm服务器故障诊断面板报警信息解释|亮黄灯了

    诊断面板如下图 xff1a ps 指示灯 xff1a 当此指示灯发亮时 xff0c 表明电源 出现故障 xff0c 需要及时更换电源 temp 指示灯 xff1a 当此指示灯发亮时 xff0c 表明系统温度超出阈值级别 xff0c 检查风扇
  • 联想x3650m5服务器安装windows2008R2系统

    服务器型号 xff1a 联想x3650 M5 2U服务器 硬盘 xff1a 一块300G硬盘 阵列 xff1a raid0 系统 xff1a windowsserver2008R2系统 安装开始时间 xff1a 20180930晚上9点 客
  • 关于IDEA模块复制问题的解决方案分享

    在IDEA开发过程中有的时候可能一些准备工作比较繁琐 xff0c 这个时候有些小伙伴们就想到了复制一个module出来导入 xff0c 但是发现各种报错不能运行 xff0c 在这里给小伙伴们分享一种IDEAmodule复制的方案 xff0c
  • Excel VBA 函数返回值

    Excel VBA 函数返回值 Sub 定义一个过程 VB的函数定义格式与C有很大区别 xff1a 格式 xff1a span class token keyword Sub span 过程名 span class token punctu
  • C#,桌面编程入门(01)——按钮Button属性与事件、动态创建、快捷键、控件数组及自定义Button

    本文是 桌面编程入门 系列文章的开山之篇 桌面编程入门 系列文章主要介绍桌面编程的各种组件 xff0c Button xff0c ComboBox xff0c Panel xff0c WebBrowser 类似的文章非常多 xff0c 深度
  • 巧用F12调试工具js修改页面加载数目

    背景 xff1a 有147页 每页显示8条记录的总数据量 xff0c 在这些数据中查找是否存在指定的一条数据 查找 xff1a 页面使用CTR 43 F功能可以快速查找确定是否存在目标数据 xff0c 或者在F12reponse里查找 xf
  • 为什么官网上下载的JDK15为什么找不到sun.misc.Launcher类?

    正常jdk8以后官网上下载到的JDK包里面是没有开放sun misc Launcher等类的 xff0c 可能是因为官方不希望用户使用这些内部的类 xff0c 因此在后面的版本里就不再开放了 xff0c 但不代表不存在 xff0c 而是以系
  • Linux自学之旅-基础命令(shutdown关机重启命令)

    Linux自学之旅 基础命令 xff08 shutdown xff09 文章目录 前言一 shutdown能做什么 xff1f 二 shutdown使用1 关机2 重启 总结 前言 1 上一节我们讲述了tar命令用来打包并压缩的用法 xff
  • Vue结合后台详解导入导出Excel问题

    Vue完整前后台项目介绍 最近Vue项目中用到了导入导出功能 xff0c 在网上搜索了一番之后 xff0c 决定采用Blob方式 xff0c 这也是大家推荐的一种的方式 xff0c 特此做下记录 导出Excel功能 这里不谈别人怎么实现的
  • Windows10 和 archlinux双系统安装及配置

    原文地址 https www viseator com 2017 05 17 arch install 第一次装archLinux时 xff0c 感觉不是很明白各个命令的大致意思 xff0c 不久前Windows的系统出问题了 xff0c
  • 银河麒麟 Qt打包

    环境 xff1a 银河麒麟4 0 2 Qt 5 12 10 将编译好的Qt程序test打包 xff0c 并部署到另一台没有开发环境的Linux下 xff0c 将过程记录如下 xff1a 将编译好的可执行程序test放到一个新建文件夹内 例如

随机推荐

  • SmartSoftHelp 自定义开源C#代码生成器

    蓦然回首终结者SmartSoftHelp开发辅助工具MiniLite2 0迷你版 V3 5 自定义生成 dbhelper Model BLL DAL sqltxt UI 方便快捷 xff0c 支持自编码 xff0c 自编译 xff0c 自己
  • 游戏开发人员需要看的书籍

    编码习惯及设计基础 程序员修炼之道 http product dangdang com 9053091 html 这本书讲解的一些设计原理很实用 对设计感兴趣的同学可以一看 推荐指数 5星 图形渲染 客户端 3D绘图程序设计 http pr
  • 【c++】生产者与消费者问题

    单个生产者和单个消费者 include lt iostream gt include lt mutex gt include lt condition variable gt include lt Windows h gt using na
  • 基于springboot人事管理系统java项目介绍

    人事管理系统是基于java编程语言 xff0c springboot框架 xff0c mysql数据库开发 xff0c 本系统分为员工和管理员两个角色 xff0c 员工的主要功能有登陆系统 xff0c 个人信息更新 xff0c 查看工资 x
  • C#,生信软件实践(02)——DNA数据库EMBL格式详解及转为FASTA格式文件的源代码

    gt 生信老白写的基础代码 fasta MAYBENOANYUSAGE EMBL 与 GenBank 文件一脉相承 xff0c 建议先阅读 GenBank 文件详解 C xff0c 生信软件实践 xff08 03 xff09 DNA数据库G
  • Activity onNewIntent详解

    onNewIntent 的触发时间 xff1a onNewIntent png 如图所示 xff0c onCreate 和 onNewIntent 不会被同时调用 官方文档 xff1a onNewIntent added in API le
  • 安装pyinstaller报错:AttributeError: type object Callable has no attribute _abc_registry

    安装pyinstaller xff1a pip install pyinstaller 提示 xff1a AttributeError type object 39 Callable 39 has no attribute 39 abc r
  • sql server 数据库开发 知识点

    sql server 数据库开发 1 含义 xff1a 数据库设计实际上就是规划和结构化数据库中的数据对象以及这些数据对象之间关系的过程 E R图组成包括 xff1a 矩形表示实体集 椭圆表示属性 菱形表示关系 直线用来连接实体集与属性 x
  • Activiti学习笔记一 工作流基本概念

    最近刚接触流程引擎这一概念 xff0c 对Activiti进行学习 xff0c 感觉正在入门中 xff0c 整理下自己的学习笔记把 xff01 1 xff1a 工作流的概念 工作流 Workflow xff0c 就是 业务过程的部分或整体在
  • Activiti学习笔记六 流程实例 任务 执行对象控制流程执行

    上一篇我们看了流程定义 xff0c 我们接下来看一下流程实例 xff0c 任务 xff0c 和执行对象 流程实例 任务的执行 1 流程图 2 部署流程定义 private final ProcessEngine processEngine
  • datetimepicker 控件验证问题

    34 baseStudents activistTime 34 trigger 39 blur 39 validators notEmpty message 39 确定积极分子时间不能为空 39 span class hljs tag lt
  • eclipse中SVN分支合并到主干

    在项目开发中 xff0c 需要添加一些新的功能 xff0c 但是又不想影响到其他开发人员的项目进度 xff0c 所以决定使用SVN分支进行开发 xff0c 分支开发完毕后再合并到主干 本文介绍如何在eclipse中合并分支到主干 要想将分支
  • 阿里云服务器

    一年多之前 xff0c 也就11年5月份的样子 xff0c 阿里云云服务器产品线终于上线了 但那时候 xff0c 国内完全没有能称得上云服务器的 xff0c 很多小公司就是搞个VPS就叫云服务器了 以至于阿里云云服务器刚出来的时候 xff0
  • mac 下 使用 iterm2 配置及快键键使用

    mac 下 使用 iterm2 配置及快键键使用 标签 xff08 空格分隔 xff09 xff1a mac 之前介绍过一篇关于mac 下使用和配置 iterm2的blog 今天这篇稍微详细一点介绍 并且搭配 zsh zsh 会单独开一篇博
  • Java实现快速排序

    一 原理 快速排序算法通过多次比较和交换来实现排序 xff0c 其排序流程如下 xff1a 1 首先设定一个分界值 xff0c 通过该分界值将数组分成左右两部分 2 将大于或等于分界值的数据集中到数组右边 xff0c 小于分界值的数据集中到
  • C#,生信软件实践(03)——DNA数据库GenBank格式详解及转为FASTA序列格式的源代码

    1 GenBank 1 1 NCBI 美国国家生物技术信息中心 xff08 美国国立生物技术信息中心 xff09 NCBI xff08 美国国立生物技术信息中心 xff09 是在NIH的国立医学图书馆 xff08 NLM xff09 的一个
  • 【坑】zsh和oh-my-zsh卸载后导致无法登陆

    apt get remove zsh 然后断开终端 xff0c 就再也连不上了 xff0c 崩溃啊 xff01 以下登陆为www用户登陆 各种找 xff0c 到这里 https www cnblogs com EasonJim p 7863
  • 获取最近使用应用列表

    获取最近使用的应用列表需要使用到UsageStatsManager类 xff0c 还需要申请允许防御应用使用情况的权限 private void getPackagesInfo UsageStatsManager manager 61 Us
  • 使用MediaProjectionManager进行截屏

    最近项目中有用到远程截屏并上传截屏文件的需求 一开始使用的是以下方法进行截屏 xff1a private void screenshot 获取屏幕 View dView 61 getWindow getDecorView dView set
  • 安卓TV开发遇到的那些坑

    最近公司需要开发一个TV的luancher xff0c 就是那种纯物理按键的遥控 xff0c 没有触摸屏 xff0c 现在说说我踩得那些坑 xff08 其实布局和代码逻辑和正常的安卓应用差不多 xff09 1 焦点 焦点 焦点 xff0c