detached HEAD state

1 detached HEAD state指的是什么

正常情况下,HEAD指向一个branch,而branch又指向一个commit。

detached HEAD state指的是HEAD指针没有指向任何的branch,比如说它指向了一个commit。比如我在某次commit处设置了一个tagXXX,然后我git checkout tagXXX,这个时候,我的HEAD就会指向这个commit。

2 detached HEAD state时我能做什么

我也可以提交,这个时候,commit链就在git checkout这个commit的基础上展开,但是如果直接离开到一个branch上的话,这些commits就会被当成garbage,被git garbage collection routine所回收。但是,我们也可以保留这些commits,又下面三种方式:

$ git checkout -b foo ,创建一个branch指向这个commit链,然后HEAD指向这个branch,于是HEAD就不是处于detached state。
$ git branch foo,创建一个branch指向这个commit链,但是HEAD还是处于detached state。
$ git tag foo,创建一个tag指向这个commit链,HEAD还是处于detached state。

3 为什么git checkout origin/XXX远程分支的时候会让HEAD进入detached state?

因为HEAD不能指向远程分支,它只能指向本地的某个commit或者本地分支。当”git checkout 远程分支”,HEAD就会直接指向远程分支指向的commit了,HEAD指向commit就会进入detached HEAD state。

 

这个时候可以

git checkout -b web-zach –track HEAD就恢复正常,并且local brach web-zach就会跟踪远程分支origin/web-zach。

 

当我git checkout [remote branch]了之后,出现了”detached HEAD state”,然后我去看HEAD文件里面是什么,cat .git/HEAD,输出直接是一个commit id,即

af7c2b39936019e386189a0bc80f5c85db637e2e。

我git checkout -b new-branch remote-branch -t之后,cat .git/HEAD,输出是一个分支,如下:

ref: refs/heads/strategy-pattern-and-sort,这个分支并且track了对应的远程分支。

4 detached HEAD state的危害

一旦出现detached HEAD state,切换分支之后,提交很可能就丢失了,被git回收了。因此要尽量避免出现这个状态。

遇到bug,要到一个老的commit版本去看一下,可以在这个commit的基础上新建一个branch,问题解决了之后删除即可。

git checkout -b new-branch-name commit

5 git checkout的本质

“git checkout branch-name”在于告诉git自己想要在哪个版本上工作,执行了这条命了之后,git会把这个版本的文件都放在working copy文件夹中。

 

转载自:https://www.cnblogs.com/hustdc/p/6444910.html

开发中遇到detached head的解决方法

detached head是一种HEAD指针指向了某一个具体的 commit id,而不是分支的情况。在这个状态下进行的commit不会对你的远程分支产生影响。先看看detached head状态下是什么情况:

1.从远程库clone下来一个远程的repository:

2. clone下来之后,git自动在本地建立了一个本地分支master,并自动与远程库master关联。此时指针指向的是一个master副本的本地分支。这个分支的内容和远程库master一致,代表你本机本地的副本。红色部分为远程分支。你在本地的分支操作(add,commit),然后push到远程的master中进行更新,远程master的更新也通过pull 与你本地的合并,以此来保持同步。

3.现在checkout到Campus_MD分支。因为本地的工作区目前是master分支的代码,checkout一下就会出现detached head的状态。在之前clone下来时,本地系统自动帮你创建了一个本地master分支与远程master关联。但是此次直接checkout Campus_MD分支时,本机上没有本地分支与之关联,就出现了detached head的情况(直接指向了commit id),所以据此猜测,应该有checkout的参数,使在checkout切换到远程分支时,自动创建一个本地分支与之对应。

就这个理解的话,那么此时只需手动在本地新建一个分支与你想要工作的分支进行关联,就会在你的工作区正常的出现 目录【分支名 ~0 ~0 ~0】这样的正常提示了。

你看,git也是这么提示的

。因为你checkout的是一个远程分支而不是本地的(因为git是一个离线的版本控制系统嘛),git只能给你一个commit id让你进行操作。这时候想正常操作,git就提示你 在此commit id的基础上新建一个分支并 与之关联(set-upstream)。就行了。

 

以前懵懂时候的操作,没有遇到detached head。clone下来之后,直接git checkout branchName ,系统就自动创建了一个新的分支,当时以为这就切换到了对应的远程分支上工作。虽然操作是正确的,但是一直没有明白其中的道理,以至于在checkout一个 origin/branchName的时候 遇到detached head就不知所措了。

 

好了,这算是最近遇到的一个git问题了,它并不是一个新问题,只是当初学习的时候一知半解留下的技术债务。

 

转载自:http://www.voidcn.com/article/p-mpanjkgu-ux.html

Git历险之-HEAD detached

前言

今天在使用git的过程中发现按照往常的commit以后再使用git push origin master命令虽然提示push成功,但是github上面没有没有显示出来,最开始以为遇到bug了,于是重新push,然而提示Everything up-to-date,百思不得其解,最后无意间使用git status命令发现了今天的主角-detached  HEAD。下面就来介绍下如何解决push成功但是github上面不显示。

解决detached  HEAD

“detached HEAD” state——HEAD头指针指向了一个具体的提交ID,而不是一个分支。

首先使用status命令查看git状态:发现HEAD detached指向了57f51ee,也就是上一次提交

$ git status

HEAD detached from 57f51ee

nothing to commit, working directory clean

然后使用branch命令查看分枝:HEAD指针指向了HEAD detached,也就是上一次的commit并没有提交到master分枝上面。

$ git branch

* (HEAD detached from 57f51ee)

master

解决方法:

使用checkout命令切换到master分枝,这是git会提示落后了一次提交,也就是上一次提交不见了。不要心急,使用git reflog即可查看所有的提交。

$ git checkout master

Warning: you are leaving 1 commit behind, not connected to

any of your branches:

我们可以看到,在57f51ee HEAD@{2}的时候,HEAD指向了57f51ee这次提交而没有指向master,当我们使用checkout命令切换到master分枝的时候(57f51ee HEAD@{0}),从最新提交e065ee0切换到了上一次提交57f51ee,所以落后了一次提交,这时我们使用reset命令直接将HEAD转向最新提交e065ee0即可。

$ git reflog

57f51ee HEAD@{0}: checkout: moving from e065ee0f51334dc72efc91dea18ad4c05912be08 to master

e065ee0 HEAD@{1}: commit: 新提交

57f51ee HEAD@{2}: checkout: moving from master to 57f51eefd108d6687bce57d04d44056d9acd3a28

57f51ee HEAD@{3}: commit: 完成主界面布局(未添加侧滑菜单等)

总结

首先使用$ git branch查看分枝,如果出现游离分枝,使用$ git checkout master切换到主分支,这时可能丢失了一次提交,使用$ git reflog查看所有提交,找到最新的提交(比如e065ee0),使用$ git reset –hard e065ee0将HEAD指向最新提交即可,然后就可以push了。

 

转载自:http://www.27house.cn/archives/676

Bitmap上下合成图片

合成两张图片,上下叠加的效果:


 

 

EventBus 3.0使用详解

EventBus 3.0使用详解

01 前言

当我们进行项目开发的时候,往往是需要应用程序的各组件、组件与后台线程间进行通信,比如在子线程中进行请求数据,当数据请求完毕后通过Handler或者是广播通知UI,而两个Fragment之家可以通过Listener进行通信等等。当我们的项目越来越复杂,使用Intent、Handler、Broadcast进行模块间通信、模块与后台线程进行通信时,代码量大,而且高度耦合。现在就让我们来学习一下EventBus 3.0吧。

02 什么是EventBus

EventBus Github地址
进入官网,看看人家是怎么解释的:

  • simplifies the communication between components
    decouples event senders and receivers
    performs well with Activities, Fragments, and background threads
    avoids complex and error-prone dependencies and life cycle issues
  • makes your code simpler
  • is fast
  • is tiny (~50k jar)
  • is proven in practice by apps with 100,000,000+ installs
  • has advanced features like delivery threads, subscriber priorities, etc.

大概的意思就是:EventBus能够简化各组件间的通信,让我们的代码书写变得简单,能有效的分离事件发送方和接收方(也就是解耦的意思),能避免复杂和容易出错的依赖性和生命周期问题。

03 关于EventBus的概述

三要素

  • Event 事件。它可以是任意类型。
  • Subscriber 事件订阅者。在EventBus3.0之前我们必须定义以onEvent开头的那几个方法,分别是onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,而在3.0之后事件处理的方法名可以随意取,不过需要加上注解@subscribe(),并且指定线程模型,默认是POSTING。
  • Publisher 事件的发布者。我们可以在任意线程里发布事件,一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可。

四种线程模型

EventBus3.0有四种线程模型,分别是:

  • POSTING (默认) 表示事件处理函数的线程跟发布事件的线程在同一个线程。
  • MAIN 表示事件处理函数的线程在主线程(UI)线程,因此在这里不能进行耗时操作。
  • BACKGROUND 表示事件处理函数的线程在后台线程,因此不能进行UI操作。如果发布事件的线程是主线程(UI线程),那么事件处理函数将会开启一个后台线程,如果果发布事件的线程是在后台线程,那么事件处理函数就使用该线程。
  • ASYNC 表示无论事件发布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行UI操作。

04 EventBus的基本用法

举个例子,我需要在一个Activity里注册EventBus事件,然后定义接收方法,这跟Android里的广播机制很像,你需要首先注册广播,然后需要编写内部类,实现接收广播,然后操作UI。所以,在EventBus中,你同样得这么做。

自定义一个事件类


 

 

这里有些同学,会有一些疑问,为什么要建立这样一个类,有什么用途。其实这个类就是一个Bean类,里面定义用来传输的数据的类型。

注册事件

 

当我们需要在Activity或者Fragment里订阅事件时,我们需要注册EventBus。我们一般选择在Activity的onCreate()方法里去注册EventBus,在onDestory()方法里,去解除注册。

解除注册


 

发送事件

 

处理事件


 

前面我们说过,处理消息的方法名字可以随便取。但是需要加一个注解@Subscribe,并且要指定线程模型。

05 EventBus使用实战

以上我们讲了EventBus的基本用法,没有用过的同学也不要担心不会用,小编在这里举个小栗子。

第一步:添加依赖


 

第二步:定义消息事件类


 

第三步:注册和解除注册

分别在FirstActivity的onCreate()方法和onDestory()方法里,进行注册EventBus和解除注册。


 

事件处理

在这里,事件的处理线程在主线程,是因为,我要让TextView去显示值。
在 SecondActivity里去进行事件的发送。


 

很简单,当点击按钮的时候,发送了一个事件。

运行程序。

 
1.PNG

 

 

在FirstActivity中,左边是一个按钮,点击之后可以跳转到SecondActivity,在按钮的右边是一个TextView,用来进行结果的验证。

 
2.PNG

这是SecondActivity,在页面的左上角,是一个按钮,当点击按钮,就会发送了一个事件,最后这个Activity就会销毁掉。

 

 
3.PNG

 

此时我们可以看到,FirstActivity里的文字已经变成了,我们在SecondActivity里设置的文字。

总结

经过这个简单的例子,我们发现EventBus使用起来是如此的方便,当我们的代码量变得很多的时候,使用EventBus后你的逻辑非常的清晰,并且代码之间高度解耦,在进行组件、页面间通信的时候,EventBus是一个不错的选择。

谢谢小伙伴啦

赞赏支持

 

 

scrollTo不起作用

最近,我在HorizontalScrollview中使用scrollTo不起作用?

……

以上省略N个字。

我只想说:

 

在使用scrollTo的时候,要先保证该HorizontalScrollview已经初始化完毕,要是无法保证,那么,可以在HorizontalScrollview中这样写

这样便能够保证在view初始化完成之后再执行scrollTo()

改变图片局部透明度,实现透明度根据位置不而渐变

最近在做项目的时候遇到了一个需求,那就是要对一张图片做处理,实现边缘模糊过渡。

苦思良久,最终用了以下的方法。

1、构成一张图片的是ARGB,我们可以直接把这整张图片的ARGB取出来,然后改变图片的A,也就是透明度。

以上我们便获得了图片的ARGB值,而我们只需要改变透明度A。

2、我们可以用

最后一句实现了只改变图片的Alpha值,(argb[i] & 0x00FFFFFF)将A全部置为0,再与((int) alpha << 24)进行或运算,那么就可以将我们的Alpha值设置进去,我们将((int) alpha)左移24位便是为了不改变RGB。

3、最后通过下面代码创建改变了透明度的bitmap

 

而我需要实现的是边缘模糊过渡,因此需要让透明度随着图片的Y坐标渐渐变为0,即过渡区域为0.我的代码如下:

 以上便实现了图片的边缘过度。

参考:https://www.cnblogs.com/Anita9002/p/4207963.html

转载请标明处处:http://77blogs.com/?p=629

在非activity类调用startActivityForResult

对于这个问题,今天折腾了一下午,不是说我不懂得怎么调用,而是我用了看似正确的调用方式,而其实这是一个坑。

我用了下面这种方式:

用这种方式是正确的,必须要将context转换为Activity。

但是由于我是在一个特殊的场景里面使用的,导致activity的onActivityResult没有被回调。

 

接下来说说我的场景:

我在MainActivity里面创建了一个DialogActivity,在DialogActivity里面调用工具类utils的start()方法,该方法里面的语句就是((Activity) mContext).startActivityForResult,而DialogActivity里面的onActivityResult没有被回调。

 

调试了半天,发现DialogActivity传进utils的start方法的context是属于MainActivity的,因为DialogActivity在MainActivity里面启动的。这么说来,相当于是MainActivity调用了startActivityForResult,应该是MainAcvtivity的onActivityResult会被回调,可是结果也不会。

 

原来MainAcvtivity与要启动的Activity之间还隔着一个DialogActivity,返回的时候是返回到DialogActivity的,因此MainActivity的onActivityResult也不会被回调。

 

解决方法,不要传context去调用,传activity

总结:((Activity) mContext).startActivityForResult,context属于哪个Activity,那么便是哪个activity调用该方法,并且想要onActivityResult获得回调,两个Activity之间不能隔着其他Activity。

 

尊重劳动成果,转载请标明出处:http://77blogs.com/?p=630

Adapter刷新数据的坑

adapter刷新数据的时候,要能够刷新成功,要保证每次刷新的时候都是改变数据源。

于是,我这样做了,在适配器的构造方法里面写到:


 

刷新数据的时候调用adapter里面的方法:(用这种方法每次刷新都是改变adapter里面的数据源,保证每次都能够刷新成功,这种思路是没错的,然而,我犯放了一个错误,导致刷新后数据被清空了)


 

我犯了什么错误呢?

我的构造方法错了,在adapter的构造方法里面,我用的是

this.listItems = listItems;

这样子传进去的listItem与adapter里面的listItem指向同一个对象,在刷新数据的方法中,我用了


 

adapter里面的listItems被清空了,导致外部传进来的listItem也被清空了,于是this.listItems.addAll(listItems);后依然为空,最终刷新数据后无反应。

转载请标明出处:http://77blogs.com/?p=632