氚云SaaS介绍文书档案

氚云SaaS

在前面包车型地铁博文中,讲过部分和Handler有关的知识,例如:

目录

Android
多线程—-AsyncTask异步职分详解 

1商店介绍2

Android三十二线程—-异步音信处理机制之Handler详解

2氚云SaaS是什么3

今日再把Handler的知识回想计算一下。

3氚云SaaS有怎样优势4

 

4氚云有何SaaS应用5

本文包涵与Handler有关的以下难题:

4.1氚云tERP5

  (1)Handler的作用

4.2氚云CRM6

  (2)为何Android中要规划为只幸好UI线程中去更新UI呢?

4.3氚云HR6

  (3)Handler的八个10分

4.4氚云资金财产管理6

  (4)Handler、Looper MessageQueue之间的关系(源码角度)

4.5费控管理7

  (5)跟线程相关的Handler,即HandlerThread(源码角度解析)

4.6氚云进销存7

  (6)主线程往子线程发音讯

4.7OKR7

 

4.8服务派单8

一、Handler的作用:

4.9品种管理8

(1)在非UI线程中做到耗费时间操作,在UI线程中去更新UI。

(2)能够在主线程中发送延时音信。

4.10门店报数8

 

4.11顾客关系管理9

② 、为啥Android中要规划为只可以在UI线程中去更新UI呢?

4.12合同管理9

(1) style=”color: #0000ff;”>缓解多线程并发难点(根本原因)

(2)升高界面更新的品质难点

(3)架构划设想计的简约

4.13会议管理9

你可能会说,既然是顾虑八线程并发难点,那笔者在子线程中加锁举办更新UI好还是不佳吗?你那样想的话,会不难造成UI卡顿的,而且质量也倒霉。

4.14扶植管理10

注1:大多数面试者很难去说出2个令面试官满足的答案。

4.15车管10

注2:关于多线程,那里举3个例子,比如说银行取款的难点。通常状态下,银行卡余额不能够不难取款金额,要是二十多线程举办取款的话,就会促成线程不安全。

5用户案例(分行业贴logo)11

注3:Android中因故说架构简单,是因为帮我们封装了好多更新UI的操作。

6支持资料12

 

 

叁 、Handler的多个万分:

2 氚云SaaS是什么

氚云SaaS应用是依照氚云PaaS平台所开发的兼具可自定义、数据互通、移动化等本性的行业深度应用。各行各业用户在氚云上,就能化解公司做安排、完善企管、升高职员和工人作功能率、集团执行力等题材。相比较于守旧的软件,氚云在网络上运转,用户不再要求独自定制软件、购买硬件,也不要求交给大笔安装与维护花费给软件厂商,客户每月只须付极少的支出如故免费就足以行使上的氚云管理选用。

在接纳Handler时,常常会冒出以下五个可怜:

葡京在线开户 1氚云SaaS有怎么着优势

 

l 任曾几何时间、任何地点访问

葡京在线开户,l 更灵敏的事务响应能力

l 一体化系统

l 更低的采办风险

l 更低的投入

l 更快的风味迭代

 

(1)CalledFromWrongThreadException:那种万分是因为尝试在子线程中去更新UI,进而发生十二分。

4 氚云有哪些SaaS应用

氚云提供贴合集团须要的吃水应用例如:氚云CHighlanderM、氚云tEWranglerP、氚云pE智跑P,从深度应用到行业方案,大家以氚云平台为底蕴,不断为铺面提供深度、全方位的与可定制的管理种类。

葡京在线开户 2 

(2)Can’t create handle inside thread that ha not called Looper.prepared:是因为我们在子线程中去创设Handler,而发出的老大。

4.1 氚云tERP

简介

氚云tE奥迪Q3P是一套针对商业贸易类公司研制的一套消息消除决方案。产品覆盖从销售、仓库储存、购买销售、财务、人事、流程管理全体管理。支持集团搭建三个简单、高效的运转管理平台,达成人、财、物、供、销通盘的治本

含有效能

√审查批准流程  √销售管制  √购买销售管理  √仓库储存管理  √财务管理 √人事管理  

 

 

 

我们接下去通过代码来把那八个格外演示一下。

4.2 氚云CRM

简介

氚云CCRUISERM帮助销售奇才对销售进度举行田管,从客户开发、外勤,联系人的敬爱,客户的跟进,商业机械的管用推进到合同的签署成交以及发票、回款等销售生命周期管理。

富含功效

√公海线索 √客户保管 √外勤跟进 √合同管理 √数据解析 √自定义作用

壹 、子线程中更新UI的百般:

4.3 氚云HR

简介

氚云H汉兰达系统是为合营社持续地升级人力能源管理水平和能力而出现的音讯化的支撑和平台。

含蓄作用

√招聘管理 √职员和工人管理 √档案管理 √薪金条 √数据报表 √流程审查批准

(1)activity_main.xml:

4.4 氚云资金财产管理

简介

氚云资金财产管理重点包蕴固定资金财产的购置入库、领用出库、资产激增、修改、转移、借用、归还、报销、维修等平时管理工作。每一种固定资金财产还是可以叠加二个基金照片,方便查看贵重物品的图像。在那之中,资金财产转移、资金财产借用、资金财产维修、资金财产报废完全完结电子化审批流程。

包含作用

√资金财产购买 √领用归还 √维修报销 √资产盘点 √资金财产总计 √资金财产清单

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"/>

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮"/>

</RelativeLayout>

4.5 费控管理

简介

氚云费控管理通过落到实处费用的集中管理与实时监察,便于降低公司资本、聚焦服务,支持公司加速完成从核算型向管理型转变,通过费用预算制定、预算调整、开支的申请、借款、报废、还款、支付全生命周期管理及流程化审查批准控制,使得集团的支出管理真正落到实处和标准运维。

饱含功效

√ 预算管理  √费用预算执行 √预算分析报表

 上方代码中,二个文书,3个按钮,代码比较不难。

4.6 氚云进销存

简介

氚云进销存软件通过简单的购买管理、销售管制、仓库管理及财务管理等作用,让每四个用户能够因而最简便的数目录入进而或许最周密的表格输出,大大简化了店铺的做事流程,升高了店铺的工效,为合营社的音信化管理提供了最方便快速的消除方案。

包罗作用

√基础数据管理 √仓库储存管理 √财务管理 √采买卖售仓库储存查询 √产品销售周转率

(2)MainActivity.java:

4.7 OKR

简介

OK卡宴应用是信用合作社实行指标管理的多个总结有效的系统,能够将目的管理自上而下贯穿到基层。有别于KIP考核方法,OKCR-V是把合适、可度量的“指标”分解为多少可量化的“关键结果”,从而协助管理职员和工人完毕指标。

富含成效

√年度指标  √季度指标  √关键结果  √工作汇报    √绩效分析

 1 import android.app.Activity;
 2 import android.os.Bundle;
 3 import android.view.View;
 4 import android.widget.Button;
 5 import android.widget.TextView;
 6 
 7 public class MainActivity extends Activity {
 8 
 9     private TextView tv;
10     private Button btn;
11 
12     @Override
13     protected void onCreate(Bundle savedInstanceState) {
14         super.onCreate(savedInstanceState);
15         setContentView(R.layout.activity_main);
16         tv = (TextView) findViewById(R.id.tv);
17         btn = (Button) findViewById(R.id.btn);
18 
19         //点击按钮后,尝试在子线程中更新UI
20         btn.setOnClickListener(new View.OnClickListener() {
21             @Override
22             public void onClick(View v) {
23 
24                 new Thread(new Runnable() {
25                     @Override
26                     public void run() {
27                         tv.setText("smyhvae");  //子线程中更新UI
28                     }
29                 }).start();
30 
31             }
32         });
33     }
34 }

4.8 服务派单

简介

简易的派单应用。集团在做售后服务时,利用工单系统来消除派单的劳作流程,并使用在于公司全体部门,帮助公司在做售后服务时,服务好它的客户。

饱含作用

√工单种类 √服务产品 √服务项目  √工单

上边代码中,大旨代码是第②7行:点击按钮后,在子线程中更新UI。

4.9 项目管理

围绕着个人或团体的周期项目,以项目同盟的艺术马上做好工作布署、让主要的品类随时显示进展情状,推进项目标实行!

涵盖功用

√项目材料 √项目报告 √项目促进 √项目晚报

 

运作程序后,点击按钮,效果如下:

4.10 门店报数

简介

门店报数应用,能够有效帮扶集团总括门店激活数据。能够化解公司限期的数码报告及集中要求,操作简易上报快、数据自动汇总、层级分明、扶助导出。

带有功用

√商品资料 √门店录入  √数据反馈  √销售分析

 

葡京在线开户 3

4.11 顾客关系管理

简介

本着2C类公司的客户关系管理采纳,提供轻量级的客户保管、销售经过管理、市场活动管理和制品质量管理理理等救助业务职员日常工作,援助业务人士及时得到客户消息,轻松跟进客户动态。

包括功用

√市集活动 √顾客保管 √会员资料 √顾客跟进 √服务工单 √销售收款 √统计报表

那时候,大家来看一下后台的log日志:

4.12 合同管理

简介

氚云合同管理应用从合同的录入登记、审查批准、履约管理、监控实施、评估、查询、总结等全生命周期的自动化作业情势,落成了铺面合同的规范化管理指标。

含蓄作用

√合同拟定 √合同履行 √合同结算 √合同质地 √合同统计分析

 

葡京在线开户 4

4.13 会议管理

简介

简单易行的会议管理选用,协助集团进步会议的规范性,效能和材质。

涵盖功效

√会议提请 √会议记录 √会议分析

 

上海体育场地中报的失实日志正是因为大家在子线程中去更新UI。

4.14 培养和磨练管理

简介

简短的营造管理选择,公司建立协会计统计一的作育流程,补助公司有效有序的团队职工培养和磨练。

富含成效

√培养和锻炼教师 √培养和锻炼科目 √培养和练习布署 √培养和磨炼总结分析

 

4.15 车管

简介

氚云车管系统针对中型小型型车队管理职员或小卖部行管人士使用.系统一切的保管单位每车使用状态及开销意况,达到总结、分析、控制的管制职能。

含蓄功效

√车辆新闻 √驾乘员消息 √用车申请 √车辆花费 √车辆事故 √车辆费用分析
√用车申请分析 

消除方案:

5 用户案例(分行业贴logo)

网络行业

 

食物行业

 

购销行业

 

当局公共关系

 

房地产

 

医药

 

餐饮

 

建工

 

生产制作

 

 

  在子线程中创设Message信息,通过Handler发给主线程,之后在Handler的handleMessage方法中收获Message音信,进而处理更新UI界面。代码如下:

6 支援资料

能够通过以下方法连忙取得解答:

在线客服: xxx

劳务电话: 四千-899-893

官方网站:www.h3yun.com

论坛社区:bbs.h3yun.com

在线摄像:http://t.cn/RiZRAlr

 1 import android.app.Activity;
 2 import android.os.Bundle;
 3 import android.os.Handler;
 4 import android.os.Message;
 5 import android.view.View;
 6 import android.view.View.OnClickListener;
 7 import android.widget.Button;
 8 import android.widget.TextView;
 9 
10 public class MainActivity extends Activity implements OnClickListener {
11     public static final int UPDATE_TEXT = 1;
12     private TextView text;
13     private Button changeText;
14 
15     //程序一加载,直接在主线程中创建Handler
16     private Handler handler = new Handler() {
17         public void handleMessage(Message msg) {
18             switch (msg.what) {
19             case UPDATE_TEXT:
20                 text.setText("Nice to meet you");
21                 break;
22             default:
23                 break;
24             }
25         }
26     };
27 
28     @Override
29     protected void onCreate(Bundle savedInstanceState) {
30         super.onCreate(savedInstanceState);
31         setContentView(R.layout.activity_main);
32         text = (TextView) findViewById(R.id.text);
33         changeText = (Button) findViewById(R.id.change_text);
34         changeText.setOnClickListener(this);
35     }
36 
37     @Override
38     public void onClick(View v) {
39         switch (v.getId()) {
40         case R.id.change_text:
41             new Thread(new Runnable() {
42                 @Override
43                 public void run() {
44                     Message message = new Message();
45                     message.what = UPDATE_TEXT;
46                     handler.sendMessage(message);
47                 }
48             }).start();
49             break;
50         default:
51             break;
52         }
53     }
54 }

 上方第四4行代码也能够换成:

Message message = handler.obtainMessage();

  

② 、在子线程中开创Handler的可怜:

MainActivity.java:

 1 import android.app.Activity;
 2 import android.os.Bundle;
 3 import android.os.Handler;
 4 import android.widget.TextView;
 5 
 6 public class MainActivity extends Activity {
 7 
 8     private TextView tv;
 9 
10     @Override
11     protected void onCreate(Bundle savedInstanceState) {
12         super.onCreate(savedInstanceState);
13         setContentView(R.layout.activity_main);
14         tv = (TextView) findViewById(R.id.tv);
15 
16         //尝试在子线程中去创建Handler
17         new Thread(new Runnable() {
18             @Override
19             public void run() {
20                 new Handler();
21             }
22         }).start();
23     }
24 }

 运转程序后, 报错如下:

葡京在线开户 5

  

四 、Handler、Looper MessageQueue之间的涉及:(源码角度)

    借使要问到Handler,那几个标题基本是面试必问的。

原理分析:

Handler是Android类库提供的用来发送、处理新闻或Runnable对象的拍卖类,它结合Message、MessageQueue和Looper类以及当前线程完结了三个新闻循环机制,用于落到实处职分的异步加载和拍卖。整个异步新闻处理流程的示意图如下图所示:

葡京在线开户 6

依据地点的图样,我们明天来分析一下异步新闻处理体制

  • Message:消息体,用于装载须要发送的对象。
  • Handler:它直接接轨自Object。效用是:在子线程中发送Message可能Runnable对象到MessageQueue中;在UI线程中收到、处理从MessageQueue分发出来的Message只怕Runnable对象。发送音信一般采取Handler的sendMessage()方法,而发出去的消息经过处理后最后会传递到Handler的handlerMessage()方法中。
  • MessageQueue:用于存放Message或Runnable对象的音讯队列。它由相应的Looper对象创制,并由Looper对象管理。每一个线程中都只会有三个MessageQueue对象。
  • Looper:是种种线程中的MessageQueue的管家,负责接收和散发Message或Runnable的做事。调用Looper.loop()方法,便是三个死循环,不断地从MessageQueue中取音信:就算有消息,就取出,并调用Handler的handlerMessage()方法;若是没有新闻阻塞。

当今能够做出如下总计:

(1)Handler负责发送新闻,Looper负责接收Handler发送的音讯放到MessageQueue,Looper又将音讯回传给Handler本人。

(2)2个Handler对应3个Looper对象,三个Looper对应3个MessageQueue对象(Looper内部涵盖2个MessageQueue),3个Handler能够变动四个Message。

(3)Handler正是公然给外部线程的接口,用于线程间的通信。Looper是由系统帮忙的用来成立和管制MessageQueue的隶属于二个线程的巡回处理指标,而Handler是用以操作线程内部的新闻队列的,所以
           Handler也不可能不依附多少个线程,而且只能是三个线程。

(4)由于Handler是在主线程中创制的,所以那时handleMessage()方法中的代码也会在主线程中运作,于是大家在此间就能够安心地进行UI操作了

 

生活中的例子:

葡京在线开户 7

上海教室中,能够那样驾驭:开会时,小编(Handler)想中途离开去做别的事情,通过sendMessage发新闻给管理者,领导思想了会儿,同意现在,通过Looper.looep()方法将音讯回传给自己,说自家得以离开,然后本身就调用handleMessage方法去做别的事情去了。

注:面试的时候,假若只是从字面包车型地铁角度来表达Handler、Looper
MessageQueue之间的关系,并不可见真的打动面试官,倒比不上再举三个鲜活的事例,让面试官觉得您是懂面向对象的思索的。

 

伍 、跟线程相关的Handler,即HandlerThread(源码角度解析)

本条难题得以看一下那篇博客:

http://blog.csdn.net/lmj623565791/article/details/47079737

 

⑥ 、主线程往子线程发音讯:(考察你是或不是真的知道Handler机制)

  大家在平常开支的长河中,平常是子线程往主线程中发新闻,让主线程更新UI。不过依据具体的类型供给,也恐怕会须求让你在主线程中往子线程中发消息。

 1 import android.app.Activity;
 2 import android.os.Bundle;
 3 import android.os.Handler;
 4 import android.os.Looper;
 5 import android.os.Message;
 6 import android.util.Log;
 7 import android.view.View;
 8 import android.view.View.OnClickListener;
 9 import android.widget.Button;
10 import android.widget.TextView;
11 
12 public class MainActivity extends Activity implements OnClickListener {
13     public static final int UPDATE_TEXT = 1;
14     private TextView tv;
15     private Button btn;
16     private Handler handler;
17 
18     @Override
19     protected void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_main);
22         tv = (TextView) findViewById(R.id.tv);
23         btn = (Button) findViewById(R.id.btn);
24         btn.setOnClickListener(this);
25         //疑问:为什么这段代码如果写在onClick方法里面会报空指针?
26         new Thread(new Runnable() {
27             @Override
28             public void run() {
29                 //1、准备Looper对象
30                 Looper.prepare();
31                 //2、在子线程中创建Handler
32                 handler = new Handler() {
33                     @Override
34                     public void handleMessage(Message msg) {
35                         super.handleMessage(msg);
36                         Log.i("handleMessage:", Thread.currentThread().getName());
37                         Log.i("后台输出", "收到了消息对象");
38                     }
39                 };
40                 //3、调用Looper的loop()方法,取出消息对象
41                 Looper.loop();
42             }
43         }).start();
44 
45     }
46     @Override
47     public void onClick(View v) {
48         Log.i("onClick:", Thread.currentThread().getName());
49         switch (v.getId()) {
50             case R.id.btn:
51                 Message msg = handler.obtainMessage();
52                 handler.sendMessage(msg);
53                 break;
54 
55             default:
56                 break;
57         }
58     }
59 }

上边的第①9行至41行代码:那是MainThread中发送音信,在子线程中收到音讯的一定写法。上边的四个步骤再另行一下:

  • 准备Looper对象
  • 在WorkerThread个中生成贰个Handler对象
  • 调用Looper的loop()方法之后,Looper对象将持续地从音讯队列个中取出对象,然后调用handler的handleMessage()方法,处理该新闻对象;假如音信队列中绝非对象,则该线程阻塞

小心,此时handleMessage()方法是在子线程中运营的。

后台运维效果:

葡京在线开户 8

微小地总结一下:

  首先实施Looper的prepare()方法,这几个格局有多少个效益:一是生成Looper对象,而是把Looper对象和当前线程对象形成键值对(线程为键),存放在ThreadLocal其中,然后生成handler对象,调用Looper的myLooper()方法,得到与Handler所对应的Looper对象,那样的话,handler、looper
、新闻队列就形成了一一对应的关联,然后实施下面的第⑦个步骤,即Looper在音讯队列个中循环的取多少。

其它,在本文最起先的第贰段中,我们在主线程中开创Handler也并未调用Looper.prepare()方法,为何就不曾崩溃呢?,这是由于在程序运行的时候,系统现已帮我们自行调用了Looper.prepare()方法。查看ActivityThread中的main()方法,代码如下所示:

 1 public static void main(String[] args) {  
 2     SamplingProfilerIntegration.start();  
 3     CloseGuard.setEnabled(false);  
 4     Environment.initForCurrentUser();  
 5     EventLogger.setReporter(new EventLoggingReporter());  
 6     Process.setArgV0("<pre-initialized>");  
 7     Looper.prepareMainLooper();  
 8     ActivityThread thread = new ActivityThread();  
 9     thread.attach(false);  
10     if (sMainThreadHandler == null) {  
11         sMainThreadHandler = thread.getHandler();  
12     }  
13     AsyncTask.init();  
14     if (false) {  
15         Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));  
16     }  
17     Looper.loop();  
18     throw new RuntimeException("Main thread loop unexpectedly exited");  
19 }  

 上方代码中,能够看出,在第10行调用了Looper.prepareMainLooper()方法,而这些主意又会再去调用Looper.prepare()方法,代码如下所示:

1 public static final void prepareMainLooper() {  
2     prepare();  
3     setMainLooper(myLooper());  
4     if (Process.supportsProcesses()) {  
5         myLooper().mQueue.mQuitAllowed = false;  
6     }  
7 } 

 总计:那样大旨就将Handler的开创进度完全搞精晓了,总结一下正是在主线程中得以一直开立Handler对象,而在子线程中须求先调用Looper.prepare()才能创建Handler对象。

 

六 、为啥在多少时候子线程中是足以平昔更新UI的:

那道面试题应该是本文中最难的1个面试题了,供给美丽精晓。为了应对这些标题,我们必要先通过看源码去了然下边那五个难题:

(1)Android是何等检查和测试非UI线程去更新UI的

(2)ViewRootImp是什么?

(3)ViewRootImp是在何地创立的?

源码作者就不贴出来了,那里作者只是总计一下。

答案:

  非UI线程真的不可能更新UI吗?
是足以的

解释:

  在线程中更新UI时会调用ViewParent.invalidateChild()方法检查当前的thread是或不是是Mainthread

切实源码如下:

1 final ViewParent p = mParent;
2     if (p != null && ai != null && l < r && t < b) {
3     final Rect damage = ai.mTmpInvalRect;
4     damage.set(l, t, r, b);
5     p.invalidateChild(this, damage);
6 }

 而ViewParent是三个接口类,其达成类是ViewRootImpl,通过翻看invalidateChild()方法里面包车型大巴代码就能够看出会他调用checkThread()方法。checkThread()方法如下:

1 void checkThread() {
2     if (mThread != Thread.currentThread()) {   //检查更新UI的线程是否是MainThread
3         throw new CalledFromWrongThreadException(
4         "Only the original thread that created a view hierarchy can touch its views.");
5     }
6 }

 上面的第02行便是检查:在线程中更新UI时当前线程是或不是是MainThread。

但是,ViewRootImpl那几个类是在activity的onResume()方法中开创的。尽管在子线程中更新UI,只要在ViewRootImpl创造从前更新UI(比如,程序在实施onCreate方法时,笔者就去履行setText方法区更新UI),就足以避开除checkThread()的反省。

关于本题,给出以下链接大家去细读一下源码吧:

Android更新Ui进阶精解(一):

http://www.jianshu.com/p/6de0a42a44d6

何以大家得以在非UI线程中更新UI:

http://blog.csdn.net/aigestudio/article/details/43449123

 

自个儿的众生号

下图是本身的微信公众号(生命团队id:vitateam),欢迎有心人关怀。新浪分享技术,公众号分享心智

笔者会很多谢第三批关切自个儿的人。这时,年轻的自个儿和您,手无寸铁;而后,富裕的您和自个儿,成绩斐然。

葡京在线开户 9