- android随笔:长按APP图标弹出快捷方式(shortcuts)
weixin_34378767
移动开发
今天的主角:Shortcuts怎么使用使用Shortcuts?Shortcuts跟BroadcastReceiver一样,可以静态注册也可以利用java代码动态注册。先来讲一下怎么静态注册StaticShortCuts首先,我们需要在res/xml目录下创建一个新的xml文件,复制代码首先一个shortcuts标签,然后是一个shortcut,到这里我们大概可以猜测到这里可以注册多个shortcu
- Android随笔3:如何判断网络断开
like26th
判断手机没网了,手机又有网了,看起来应该是个很基础的功能,但是我总感觉实现起来有点别扭。以前判断网络是否连接的时候是ping一下服务器,这个方法目前看还是万无一失,ping不通App就没有数据,除非服务器挂了。try{//-c3ping3次,-w60超时时间为60秒Processp=Runtime.getRuntime().exec("ping-c3-w60"+"服务器ip地址");returnp
- Android随笔-真机调试时无法直接启动应用
阿pin
Androidandroidandroidstudioreactnative
描述真机调试时,提示Launchsucceeded,且Installsuccessfullyfinished,但是应用并没有被打开。解决方案检查MainActivity的export是否为true,默认情况下export为true,有时为了防止应用被其他应用组件启动,会将export设为false,此时应用只能由具有相同用户ID的相同应用程序或应用程序的组件启动。
- Android随笔之Android Studio常用设置以及一些奇技
leiliang568
androidandroidandroidstudio
AndroidStudio的一些常用设置一、自动编译相关File->Setting->Compile如图:自动Mask这里测试到两个设置:.自动编译选项这是另一个节省时间的编译选项,可以在更改代码时触发项目自动编译。由于编译器运行在一个单独的进程,因此可以在后台编译修改过的文件。这意味着你的项目一直都可处于编译状态,无需等待。.编译器设置可以通过Settings→Compiler来对编译器进行设置
- Android随笔之算法题解
android老菜鸟
Test1:给定一个有符号整型数,将这个数字反转并输出给定123输出321解题思路:privateintreversal_2(intn){inttemp=0;intm=0;while(n!=0){m=m*10+n%10;//取个位if(temp!=m/10){//根据补码运算规则,如果发生了溢出那么temp和m/10的值一定不相等return0;}temp=m;n=n/10;}returnm;}T
- Android随笔-RelativeLayout代码中控制子View的位置
阿pin
AndroidAndroid
描述Android中页面开发常在xml中进行开发,在Java代码中直接创建使用的比较少,其中LinearLayout的使用比较简单,直接向其中添加子View即可;但是对于RelativeLayout来讲,RelativeLayout中的子View的位置都是根据彼此的id来控制的,很多可能在代码中使用不太熟悉。开发以RelativeLayout为父容器,向其中添加两个子View,要求第二个添加的Vi
- Android随笔之反射
android老菜鸟
多的不说,少的不唠,直接入题:得到Class的三种方式1、通过对象调用getClass()方法来获取,通常应用在:比如你传过来一个Object类型的对象,而我不知道你具体是什么类,用这种方法Personp1=newPerson();Classc1=p1.getClass();2、直接通过类名.class的方式得到,该方法最为安全可靠,程序性能更高这说明任何一个类都有一个隐含的静态成员变量class
- Android随笔-VPN判断
阿pin
AndroidJavaBugandroid
Android中判断当前网络是否为VPN/***判断当前网络是否为VPN*@paramcontext*@return*/publicstaticbooleanhasVPN(Contextcontext){//查询网络状态,被动监听网络状态变化ConnectivityManagercm=(ConnectivityManager)context.getSystemService(Context.CON
- android随笔之Hook
android老菜鸟
Hook的选择点:静态变量和单例,因为一旦创建对象,它们不容易变化,非常容易定位。Hook过程:寻找Hook点,原则是静态变量或者单例对象,尽量Hookpublic的对象和方法。选择合适的代理方式,如果是接口可以用动态代理。偷梁换柱——用代理对象替换原始对象。
- android随笔之为什么属性动画移动一个控件后,目标位置仍然能响应用户事件?补间动画就不行呢?
android老菜鸟
如题,多的不说,少的不唠,直接入主题:为什么属性动画移动一个控件后,目标位置仍然能响应用户事件?也就是说,应用了属性动画之后,该View依然可以正确地接收到事件的分派。那就要搞清楚ViewGroup它是怎么找到这个"偷跑"了的View的。我们知道,调用View的translationXX方法之后,虽然在屏幕上的位置是变了,但是它的[left,top,right,bottom]是不会变的。来捋一遍V
- Android随笔之——Android单元测试
ib26nqt202
在实际开发中,开发android软件的过程需要不断地进行测试。所以掌握Android的单元测试是极其重要的。您应该把单元测试作为Android应用开发周期的一部分,精心编写的测试可以在开发早起帮你发现错误。关于Android单元测试可以看Google官方给的教程:BestPracticesforTesting(需要FQ)一、创建AndroidTestProject1、创建一个AndroidProj
- android随笔之序列化Parcelable与Serializable的性能比较
android老菜鸟
大家都知道,Parcelable与Serializable都可以进行序列化,但是它们到底有什么区别呢?我的理解如下:1,Serializable的作用是为了保存对象的属性到本地文件、数据库,以方便数据传输,当然这种传输可以是程序内也可以是程序间的。而Parcelable的设计初衷是因为Serializable效率过慢,为了程序内不同组件间以及不同程序间高效的传输而设计,这些数据仅在内存中存在,Pa
- android随笔之面试题汇总(JAVA篇)
android老菜鸟
基础篇int与integer的区别Integer对象会占用更多的内存。Integer是一个对象,需要存储对象的元数据。但是int是一个原始类型的数据,所以占用的空间更少。int和Integer的更多区别:1.两个通过new出来的Integer变量比较,结果为false。/***比较两个new出来的Integer*/publicclassTest{publicstaticvoidmain(Strin
- Android随笔 -- 记录自己看过的比较好的技术类文章链接
宅出一条路
android随笔androidjava
1.作者:brave-sailor(博客)https://www.cnblogs.com/Free-Thinker/category/507472.html2.作者:Threeyears(博客)TextView淡入淡出效果https://www.cnblogs.com/tyrion/p/4337630.html
- android随笔之自定义圆形刻度条
android老菜鸟
多的不说,少的不唠,上图Screenshot_1601283851.png自定义view的流程就不多说了,网上一大堆,直接上代码。1,自定义style//半径//外环宽//外环高2,自定义viewpublicclassCircleProgressViewextendsViewimplementsValueAnimator.AnimatorUpdateListener{//默认颜色privatein
- android随笔之大图加载
android老菜鸟
多的不说,少的不唠,上图:1603334406103(1).gif实现思路:局部加载,触摸拖动,双击缩放开搞:一些初始化mRect=newRect();mOptions=newBitmapFactory.Options();//手势mGestureDetector=newGestureDetector(context,this);//滚动mScroller=newScroller(context)
- android模拟按键方法,Android随笔之——模拟按键操作的几种方式
找寻生命的意义
android模拟按键方法
前几天转过一篇Android上模拟按键操作、触屏事件的博客,昨天又去找了百度、谷歌了一下,写了一点简单的测试代码,留待不时之需。有需要看之前转载的那篇博客的请看这里→_→转:Android随笔之——使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵),这里我就直接上代码了。packagecom.lsj.keyboardsample;importandroid.app.Activity
- Android随笔-Room简单使用
阿pin
Androidandroidsqlite数据库
概述处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的使用场景是缓存相关的数据,这样一来,当设备无法访问网络时,用户仍然可以在离线状态下浏览该内容。Room持久性库在SQLite上提供了一个抽象层,以便在充分利用SQLite的强大功能的同时,能够流畅地访问数据库。具体来说,Room具有以下优势:针对SQL查询的编译时验证。可最大限度减少重复和容易出错的样板代码的方便注解。简化了数据
- android随笔之自定义渐变进度条
android老菜鸟
多的不说,少的不唠,上图Screenshot_1601345389.png自定义view的流程又不多说了,网上一大堆,直接上代码,咦,我为什么说了个又字?好吧,不管了,上代码。1,自定义style2,自定义viewpackagecom.rsw.rswtestdemo.views;importandroid.content.Context;importandroid.content.res.Type
- Android随笔——搞定流动布局(FlexboxLayout)
QuincySx
转载请标明地址QuincySx:[http://www.jianshu.com/p/fbeb3808a17f]简介FlexboxLayout是Google推出的一个布局,它的作用就和LinearLayout相似,如果只是功能相似的话,那个谷歌就没有推出他的必要性了,他是一个聪明的布局,他和LinearLayout最大的区别就是能够换行,并且可以和RecyclerView无缝使用,今天我们就一点点的
- Android随笔之Realm
圈圈猫
在Android中数据的存储无非就这么几种,数据库、sharedpreference、文件、内存、网络、内容提供者也算一个。sharedpreference结构是类似XML键值对方式存储的,然后和文件一样,如果用于查找数据就明显是鸡肋了。这个时候就需要使用sqlite,sqlite可以满足大部分用于的查询要求,但使用它的病垢就是代码量太多了。因此在这样的环境下realm就诞生了,realm可以和当
- android随笔之开发UI开源库
android老菜鸟
Android开发UI开源库按钮https://github.com/hoang8f/android-flat-button很适合做扁平化、纯色的按钮,支持阴影。https://github.com/Bearded-Hen/Android-BootstrapBootStrap风格的按钮,做过前端的同学应该都知道。https://github.com/dmytrodanylyk/circular-p
- android随笔之MVVM简单框架:Mvvm+Androidx+JectPack(LifeCycle、ViewModel、LiveData)
android老菜鸟
最近闲着无聊,写了个简单的mvvmdemo(还未完成,先凑合看吧),先上几张图微信图片_20201022111945.jpg微信图片_20201022111948.jpg微信图片_20201022110215.jpg☞完整Demo请移步RswMvvmDemo喜欢的请给个Star☆!!服务器是自己写的,java开发,不考虑性能问题,毕竟不是专业写后端的,需要服务端代码的评论区留个言,数据来源于网络每
- android随笔之深入理解HashMap原理
android老菜鸟
本文涉及HashMap的知识点有:1,HashMap的简单使用2,HashMap的存储结构原理3,HashMap的扩容方法原理4,HashMap中定位数据索引实现5,HashMap中put、get方法实现HashMap的简单使用HashMap使用键值对存储,只需传入相应的键-值即可存储。HashMapmap=newHashMap();map.put("key1",1);map.put("key2"
- android随笔之Handler.post()和View.post()区别
android老菜鸟
newHandler().post(newRunnable(){@Overridepublicvoidrun(){System.out.println("mFlowLayout.getMeasuredHeight()==222====="+mFlowLayout.getMeasuredHeight());System.out.println("mFlowLayout.getMeasuredWidt
- android随笔15——注册锁屏广播以及…
大大怪蜀黍
android随笔
*锁屏时,清理后台进程*@authorAdministratorpublicclassLockClearServiceextendsService{@OverridepublicIBinderonBind(Intentintent){returnnull;}privateclassLockScreenReceiverextendsBroadcastReceiver{@Overridepublicv
- 自学android随笔(一)Error:failed to find target android-24
HYQHYQ111
android
因为是为了记录自己学习过程中遇到的一些问题,所以总体叙述很随性。第一次安装androidstudio出现Error:failedtofindtargetandroid-24:D:\Androidstudio\android-sdk-windowsInstallmissingplatform(s)andsyncproject”我在网上找了一下解决办法,但是没有遇到和我一样的,我找到了一个:Error
- 自学android随笔(三)修改API+按钮与文本框事件的处理+圆角透明文本
HYQHYQ111
androidandroid
几个月了吧,都没好好研究安卓了,迫于老师的要求也就做了一个计算个人所得税的小软件。在此记一下我在制作时候需要记下得东西,下次就不要在百度了。一:修改API这个之前已经改过了但是还是没记住:二:点击按钮然后获取用户文本框的内容+将一些东西显现在用户界面的文本框中Buttonbtn=(Button)findViewById(R.id.jisuan);//获取计算这个按钮Buttonclean=(But
- Android随笔3:多行RadioGroup
jaloast
安卓开发自定义控件UI控件
一、简介在开发某APP时,遇到这么一个问题:要使用RadioGroup来实现单选框效果,但是item太多,要分成两行来显示。一开始我心想,这不是很简单吗,在xml布局里设置RadioGroup的orientation值为vertical,里面嵌套一个水平布局的LinearLayout,然后把RadioButton给它一个一个摆上去不就完事儿咯~soeasy的事情,万万没想到。。。。。。什么鬼???
- android随笔25——搜索框输入内容后界面的隐藏逻辑
大大怪蜀黍
android随笔
xml文件java文件packagecom.xxx.xxximportjava.util.ArrayList;importjava.util.List;importorg.kymjs.aframe.http.KJHttp;importorg.kymjs.aframe.http.KJStringParams;importorg.kymjs.aframe.http.StringCallBack;imp
- Maven
Array_06
eclipsejdkmaven
Maven
Maven是基于项目对象模型(POM), 信息来管理项目的构建,报告和文档的软件项目管理工具。
Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具。由于 Maven 的缺省构建规则有较高的可重用性,所以常常用两三行 Maven 构建脚本就可以构建简单的项目。由于 Maven 的面向项目的方法,许多 Apache Jakarta 项目发文时使用 Maven,而且公司
- ibatis的queyrForList和queryForMap区别
bijian1013
javaibatis
一.说明
iBatis的返回值参数类型也有种:resultMap与resultClass,这两种类型的选择可以用两句话说明之:
1.当结果集列名和类的属性名完全相对应的时候,则可直接用resultClass直接指定查询结果类
- LeetCode[位运算] - #191 计算汉明权重
Cwind
java位运算LeetCodeAlgorithm题解
原题链接:#191 Number of 1 Bits
要求:
写一个函数,以一个无符号整数为参数,返回其汉明权重。例如,‘11’的二进制表示为'00000000000000000000000000001011', 故函数应当返回3。
汉明权重:指一个字符串中非零字符的个数;对于二进制串,即其中‘1’的个数。
难度:简单
分析:
将十进制参数转换为二进制,然后计算其中1的个数即可。
“
- 浅谈java类与对象
15700786134
java
java是一门面向对象的编程语言,类与对象是其最基本的概念。所谓对象,就是一个个具体的物体,一个人,一台电脑,都是对象。而类,就是对象的一种抽象,是多个对象具有的共性的一种集合,其中包含了属性与方法,就是属于该类的对象所具有的共性。当一个类创建了对象,这个对象就拥有了该类全部的属性,方法。相比于结构化的编程思路,面向对象更适用于人的思维
- linux下双网卡同一个IP
被触发
linux
转自:
http://q2482696735.blog.163.com/blog/static/250606077201569029441/
由于需要一台机器有两个网卡,开始时设置在同一个网段的IP,发现数据总是从一个网卡发出,而另一个网卡上没有数据流动。网上找了下,发现相同的问题不少:
一、
关于双网卡设置同一网段IP然后连接交换机的时候出现的奇怪现象。当时没有怎么思考、以为是生成树
- 安卓按主页键隐藏程序之后无法再次打开
肆无忌惮_
安卓
遇到一个奇怪的问题,当SplashActivity跳转到MainActivity之后,按主页键,再去打开程序,程序没法再打开(闪一下),结束任务再开也是这样,只能卸载了再重装。而且每次在Log里都打印了这句话"进入主程序"。后来发现是必须跳转之后再finish掉SplashActivity
本来代码:
// 销毁这个Activity
fin
- 通过cookie保存并读取用户登录信息实例
知了ing
JavaScripthtml
通过cookie的getCookies()方法可获取所有cookie对象的集合;通过getName()方法可以获取指定的名称的cookie;通过getValue()方法获取到cookie对象的值。另外,将一个cookie对象发送到客户端,使用response对象的addCookie()方法。
下面通过cookie保存并读取用户登录信息的例子加深一下理解。
(1)创建index.jsp文件。在改
- JAVA 对象池
矮蛋蛋
javaObjectPool
原文地址:
http://www.blogjava.net/baoyaer/articles/218460.html
Jakarta对象池
☆为什么使用对象池
恰当地使用对象池化技术,可以有效地减少对象生成和初始化时的消耗,提高系统的运行效率。Jakarta Commons Pool组件提供了一整套用于实现对象池化
- ArrayList根据条件+for循环批量删除的方法
alleni123
java
场景如下:
ArrayList<Obj> list
Obj-> createTime, sid.
现在要根据obj的createTime来进行定期清理。(释放内存)
-------------------------
首先想到的方法就是
for(Obj o:list){
if(o.createTime-currentT>xxx){
- 阿里巴巴“耕地宝”大战各种宝
百合不是茶
平台战略
“耕地保”平台是阿里巴巴和安徽农民共同推出的一个 “首个互联网定制私人农场”,“耕地宝”由阿里巴巴投入一亿 ,主要是用来进行农业方面,将农民手中的散地集中起来 不仅加大农民集体在土地上面的话语权,还增加了土地的流通与 利用率,提高了土地的产量,有利于大规模的产业化的高科技农业的 发展,阿里在农业上的探索将会引起新一轮的产业调整,但是集体化之后农民的个体的话语权 将更少,国家应出台相应的法律法规保护
- Spring注入有继承关系的类(1)
bijian1013
javaspring
一个类一个类的注入
1.AClass类
package com.bijian.spring.test2;
public class AClass {
String a;
String b;
public String getA() {
return a;
}
public void setA(Strin
- 30岁转型期你能否成为成功人士
bijian1013
成功
很多人由于年轻时走了弯路,到了30岁一事无成,这样的例子大有人在。但同样也有一些人,整个职业生涯都发展得很优秀,到了30岁已经成为职场的精英阶层。由于做猎头的原因,我们接触很多30岁左右的经理人,发现他们在职业发展道路上往往有很多致命的问题。在30岁之前,他们的职业生涯表现很优秀,但从30岁到40岁这一段,很多人
- [Velocity三]基于Servlet+Velocity的web应用
bit1129
velocity
什么是VelocityViewServlet
使用org.apache.velocity.tools.view.VelocityViewServlet可以将Velocity集成到基于Servlet的web应用中,以Servlet+Velocity的方式实现web应用
Servlet + Velocity的一般步骤
1.自定义Servlet,实现VelocityViewServl
- 【Kafka十二】关于Kafka是一个Commit Log Service
bit1129
service
Kafka is a distributed, partitioned, replicated commit log service.这里的commit log如何理解?
A message is considered "committed" when all in sync replicas for that partition have applied i
- NGINX + LUA实现复杂的控制
ronin47
lua nginx 控制
安装lua_nginx_module 模块
lua_nginx_module 可以一步步的安装,也可以直接用淘宝的OpenResty
Centos和debian的安装就简单了。。
这里说下freebsd的安装:
fetch http://www.lua.org/ftp/lua-5.1.4.tar.gz
tar zxvf lua-5.1.4.tar.gz
cd lua-5.1.4
ma
- java-14.输入一个已经按升序排序过的数组和一个数字, 在数组中查找两个数,使得它们的和正好是输入的那个数字
bylijinnan
java
public class TwoElementEqualSum {
/**
* 第 14 题:
题目:输入一个已经按升序排序过的数组和一个数字,
在数组中查找两个数,使得它们的和正好是输入的那个数字。
要求时间复杂度是 O(n) 。如果有多对数字的和等于输入的数字,输出任意一对即可。
例如输入数组 1 、 2 、 4 、 7 、 11 、 15 和数字 15 。由于
- Netty源码学习-HttpChunkAggregator-HttpRequestEncoder-HttpResponseDecoder
bylijinnan
javanetty
今天看Netty如何实现一个Http Server
org.jboss.netty.example.http.file.HttpStaticFileServerPipelineFactory:
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast(&quo
- java敏感词过虑-基于多叉树原理
cngolon
违禁词过虑替换违禁词敏感词过虑多叉树
基于多叉树的敏感词、关键词过滤的工具包,用于java中的敏感词过滤
1、工具包自带敏感词词库,第一次调用时读入词库,故第一次调用时间可能较长,在类加载后普通pc机上html过滤5000字在80毫秒左右,纯文本35毫秒左右。
2、如需自定义词库,将jar包考入WEB-INF工程的lib目录,在WEB-INF/classes目录下建一个
utf-8的words.dict文本文件,
- 多线程知识
cuishikuan
多线程
T1,T2,T3三个线程工作顺序,按照T1,T2,T3依次进行
public class T1 implements Runnable{
@Override
 
- spring整合activemq
dalan_123
java spring jms
整合spring和activemq需要搞清楚如下的东东1、ConnectionFactory分: a、spring管理连接到activemq服务器的管理ConnectionFactory也即是所谓产生到jms服务器的链接 b、真正产生到JMS服务器链接的ConnectionFactory还得
- MySQL时间字段究竟使用INT还是DateTime?
dcj3sjt126com
mysql
环境:Windows XPPHP Version 5.2.9MySQL Server 5.1
第一步、创建一个表date_test(非定长、int时间)
CREATE TABLE `test`.`date_test` (`id` INT NOT NULL AUTO_INCREMENT ,`start_time` INT NOT NULL ,`some_content`
- Parcel: unable to marshal value
dcj3sjt126com
marshal
在两个activity直接传递List<xxInfo>时,出现Parcel: unable to marshal value异常。 在MainActivity页面(MainActivity页面向NextActivity页面传递一个List<xxInfo>): Intent intent = new Intent(this, Next
- linux进程的查看上(ps)
eksliang
linux pslinux ps -llinux ps aux
ps:将某个时间点的进程运行情况选取下来
转载请出自出处:http://eksliang.iteye.com/admin/blogs/2119469
http://eksliang.iteye.com
ps 这个命令的man page 不是很好查阅,因为很多不同的Unix都使用这儿ps来查阅进程的状态,为了要符合不同版本的需求,所以这个
- 为什么第三方应用能早于System的app启动
gqdy365
System
Android应用的启动顺序网上有一大堆资料可以查阅了,这里就不细述了,这里不阐述ROM启动还有bootloader,软件启动的大致流程应该是启动kernel -> 运行servicemanager 把一些native的服务用命令启动起来(包括wifi, power, rild, surfaceflinger, mediaserver等等)-> 启动Dalivk中的第一个进程Zygot
- App Framework发送JSONP请求(3)
hw1287789687
jsonp跨域请求发送jsonpajax请求越狱请求
App Framework 中如何发送JSONP请求呢?
使用jsonp,详情请参考:http://json-p.org/
如何发送Ajax请求呢?
(1)登录
/***
* 会员登录
* @param username
* @param password
*/
var user_login=function(username,password){
// aler
- 发福利,整理了一份关于“资源汇总”的汇总
justjavac
资源
觉得有用的话,可以去github关注:https://github.com/justjavac/awesome-awesomeness-zh_CN 通用
free-programming-books-zh_CN 免费的计算机编程类中文书籍
精彩博客集合 hacke2/hacke2.github.io#2
ResumeSample 程序员简历
- 用 Java 技术创建 RESTful Web 服务
macroli
java编程WebREST
转载:http://www.ibm.com/developerworks/cn/web/wa-jaxrs/
JAX-RS (JSR-311) 【 Java API for RESTful Web Services 】是一种 Java™ API,可使 Java Restful 服务的开发变得迅速而轻松。这个 API 提供了一种基于注释的模型来描述分布式资源。注释被用来提供资源的位
- CentOS6.5-x86_64位下oracle11g的安装详细步骤及注意事项
超声波
oraclelinux
前言:
这两天项目要上线了,由我负责往服务器部署整个项目,因此首先要往服务器安装oracle,服务器本身是CentOS6.5的64位系统,安装的数据库版本是11g,在整个的安装过程中碰到很多的坑,不过最后还是通过各种途径解决并成功装上了。转别写篇博客来记录完整的安装过程以及在整个过程中的注意事项。希望对以后那些刚刚接触的菜鸟们能起到一定的帮助作用。
安装过程中可能遇到的问题(注
- HttpClient 4.3 设置keeplive 和 timeout 的方法
supben
httpclient
ConnectionKeepAliveStrategy kaStrategy = new DefaultConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
long keepAlive
- Spring 4.2新特性-@Import注解的升级
wiselyman
spring 4
3.1 @Import
@Import注解在4.2之前只支持导入配置类
在4.2,@Import注解支持导入普通的java类,并将其声明成一个bean
3.2 示例
演示java类
package com.wisely.spring4_2.imp;
public class DemoService {
public void doSomethin