Skip to content

Commit 2bcc3cb

Browse files
author
Dmytro Voronkevych
committed
Fixed NPE when removeCallbacks() called concurrently
1 parent c0e1a5d commit 2bcc3cb

File tree

5 files changed

+371
-175
lines changed

5 files changed

+371
-175
lines changed

build.gradle

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,45 @@
1818
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1919
* THE SOFTWARE.
2020
*/
21-
project.ext.set('VERSION_CODE', 1)
22-
project.ext.set('VERSION_NAME', '1.0')
21+
project.ext.set('VERSION_CODE', 2)
22+
project.ext.set('VERSION_NAME', '1.1')
2323

2424
buildscript {
2525
repositories {
2626
mavenCentral()
2727
}
2828

2929
dependencies {
30-
classpath 'com.android.tools.build:gradle:0.12.+'
30+
classpath 'com.android.tools.build:gradle:1.2.3'
3131
}
3232
}
3333

3434
apply plugin: 'com.android.library'
3535

36+
repositories {
37+
mavenCentral()
38+
}
39+
3640
dependencies {
37-
compile "com.android.support:support-annotations:19.1.0"
41+
compile "com.android.support:support-annotations:22.2.0"
42+
androidTestCompile 'junit:junit:4.12'
43+
androidTestCompile('com.android.support.test:runner:0.2') {
44+
exclude group: 'junit'
45+
}
3846
}
3947

4048

4149
android {
42-
compileSdkVersion 19
43-
buildToolsVersion "19.1.0"
50+
compileSdkVersion 22
51+
buildToolsVersion "22.0.1"
4452

4553
defaultConfig {
4654
versionCode project.VERSION_CODE
4755
versionName project.VERSION_NAME
4856
minSdkVersion 8
49-
targetSdkVersion 19
57+
targetSdkVersion 22
58+
59+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
5060
}
5161
}
5262

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Wed Aug 27 15:30:55 BST 2014
1+
#Tue Jun 02 19:11:40 BST 2015
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-bin.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package com.badoo.mobile.util;
2+
3+
import android.support.test.runner.AndroidJUnit4;
4+
import android.test.suitebuilder.annotation.SmallTest;
5+
6+
import org.junit.Before;
7+
import org.junit.Test;
8+
import org.junit.runner.RunWith;
9+
10+
import java.util.concurrent.locks.Lock;
11+
import java.util.concurrent.locks.ReentrantLock;
12+
13+
import static junit.framework.Assert.assertNull;
14+
import static junit.framework.Assert.assertSame;
15+
16+
/**
17+
* Tests for {@link com.badoo.mobile.util.WeakHandler.ChainedRef}
18+
*
19+
* @author Dmytro Voronkevych
20+
*/
21+
@SuppressWarnings("ALL")
22+
@SmallTest
23+
@RunWith(AndroidJUnit4.class)
24+
public class WeakHandlerChainedRefTest {
25+
26+
private Runnable mHeadRunnable;
27+
private Runnable mFirstRunnable;
28+
private Runnable mSecondRunnable;
29+
private Lock mLock;
30+
private WeakHandler.ChainedRef mRefHead;
31+
private WeakHandler.ChainedRef mFirst;
32+
private WeakHandler.ChainedRef mSecond;
33+
private WeakHandler.WeakRunnable mHeadWeakRunnable;
34+
private WeakHandler.WeakRunnable mFirstWeakRunnable;
35+
private WeakHandler.WeakRunnable mSecondWeakRunnable;
36+
37+
@Before
38+
public void setUp() {
39+
mLock = new ReentrantLock();
40+
41+
mHeadRunnable = new DummyRunnable();
42+
mFirstRunnable = new DummyRunnable();
43+
mSecondRunnable = new DummyRunnable();
44+
45+
mRefHead = new WeakHandler.ChainedRef(mLock, mHeadRunnable) {
46+
@Override
47+
public String toString() {
48+
return "refHead";
49+
}
50+
};
51+
mFirst = new WeakHandler.ChainedRef(mLock, mFirstRunnable) {
52+
@Override
53+
public String toString() {
54+
return "first";
55+
}
56+
};
57+
mSecond = new WeakHandler.ChainedRef(mLock, mSecondRunnable) {
58+
@Override
59+
public String toString() {
60+
return "second";
61+
}
62+
};
63+
64+
mRefHead.insertAbove(mFirst);
65+
mRefHead.insertAbove(mSecond);
66+
67+
mHeadWeakRunnable = mRefHead.wrapper;
68+
mFirstWeakRunnable = mFirst.wrapper;
69+
mSecondWeakRunnable = mSecond.wrapper;
70+
}
71+
72+
@Test
73+
public void insertAbove() {
74+
assertSame(mSecond, mRefHead.next);
75+
assertSame(mFirst, mRefHead.next.next);
76+
assertNull(mRefHead.next.next.next);
77+
78+
assertNull(mRefHead.prev);
79+
assertSame(mSecond, mFirst.prev);
80+
assertSame(mRefHead, mSecond.prev);
81+
}
82+
83+
@Test
84+
public void removeFirst() {
85+
mFirst.remove();
86+
assertNull(mFirst.next);
87+
assertNull(mFirst.prev);
88+
89+
assertSame(mSecond, mRefHead.next);
90+
assertSame(mRefHead, mSecond.prev);
91+
assertNull(mSecond.next);
92+
}
93+
94+
@Test
95+
public void removeSecond() {
96+
mSecond.remove();
97+
98+
assertNull(mSecond.next);
99+
assertNull(mSecond.prev);
100+
101+
assertSame(mFirst, mRefHead.next);
102+
assertNull(mFirst.next);
103+
assertSame(mRefHead, mFirst.prev);
104+
}
105+
106+
@Test
107+
public void removeFirstByRunnable() {
108+
assertSame(mFirstWeakRunnable, mRefHead.remove(mFirstRunnable));
109+
assertSame(mRefHead.next, mSecond);
110+
assertSame(mRefHead, mSecond.prev);
111+
assertNull(mSecond.next);
112+
}
113+
114+
@Test
115+
public void removeSecondByRunnable() {
116+
assertSame(mSecondWeakRunnable, mRefHead.remove(mSecondRunnable));
117+
assertSame(mFirst, mRefHead.next);
118+
assertSame(mRefHead, mFirst.prev);
119+
}
120+
121+
@Test
122+
public void removeUnexistentRunnableReturnNull() {
123+
assertNull(mRefHead.remove(new DummyRunnable()));
124+
assertSame(mSecond, mRefHead.next);
125+
assertNull(mFirst.next);
126+
assertSame(mSecond, mFirst.prev);
127+
assertSame(mRefHead, mSecond.prev);
128+
}
129+
130+
private class DummyRunnable implements Runnable {
131+
@Override
132+
public void run() {
133+
}
134+
}
135+
}

0 commit comments

Comments
 (0)