Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
huanghaihua
committed
Aug 31, 2019
1 parent
fb95359
commit d4a20e5
Showing
15 changed files
with
840 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.hhh.app; | ||
|
||
import android.os.Bundle; | ||
import android.widget.Toast; | ||
|
||
import com.hhh.liveeventbus.LiveEventBus; | ||
|
||
import androidx.appcompat.app.AppCompatActivity; | ||
import androidx.fragment.app.FragmentActivity; | ||
|
||
public class MainActivity extends AppCompatActivity { | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
setContentView(R.layout.activity_main); | ||
testSendEvent(); | ||
testAcceptEvent(this); | ||
} | ||
|
||
private void testSendEvent() { | ||
findViewById(R.id.post).setOnClickListener(view -> LiveEventBus.getInstance() | ||
.with(TestEvent.class).post(new TestEvent("post"))); | ||
findViewById(R.id.post_delay).setOnClickListener(view -> LiveEventBus.getInstance() | ||
.with(TestEvent.class).postDelay(new TestEvent("postDelay"), 1000L)); | ||
findViewById(R.id.post_orderly).setOnClickListener(view -> LiveEventBus.getInstance() | ||
.with(TestEvent.class).postOrderly(new TestEvent("postOrderly"))); | ||
} | ||
|
||
private void testAcceptEvent(FragmentActivity activity) { | ||
findViewById(R.id.observe).setOnClickListener( | ||
view -> LiveEventBus.getInstance().with(TestEvent.class).observe(activity, | ||
testEvent -> Toast.makeText(activity, testEvent.mEvent, Toast.LENGTH_SHORT).show())); | ||
findViewById(R.id.observe_sticky).setOnClickListener(view -> LiveEventBus.getInstance() | ||
.with(TestEvent.class).observeSticky(activity, testEvent -> Toast | ||
.makeText(activity, "stick: " + testEvent.mEvent, Toast.LENGTH_SHORT).show())); | ||
findViewById(R.id.observe_forever).setOnClickListener( | ||
view -> LiveEventBus.getInstance().with(TestEvent.class).observeForever(testEvent -> Toast | ||
.makeText(activity, "forever: " + testEvent.mEvent, Toast.LENGTH_SHORT).show())); | ||
findViewById(R.id.observe_sticky_forever).setOnClickListener(view -> LiveEventBus.getInstance() | ||
.with(TestEvent.class).observeStickyForever(testEvent -> Toast | ||
.makeText(activity, "sticky_forever: " + testEvent.mEvent, Toast.LENGTH_SHORT).show())); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.hhh.app; | ||
|
||
import androidx.annotation.NonNull; | ||
|
||
public final class TestEvent { | ||
|
||
public final String mEvent; | ||
|
||
public TestEvent(@NonNull String event) { | ||
mEvent = event; | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,57 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<androidx.constraintlayout.widget.ConstraintLayout | ||
xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
xmlns:app="http://schemas.android.com/apk/res-auto" | ||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:app="http://schemas.android.com/apk/res-auto" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
tools:context=".MainActivity"> | ||
|
||
<Button | ||
android:id="@+id/post" | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:text="post" | ||
app:layout_constraintTop_toTopOf="parent" /> | ||
|
||
<Button | ||
android:id="@+id/post_delay" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
tools:context=".MainActivity"> | ||
android:layout_height="wrap_content" | ||
android:text="post_delay" | ||
app:layout_constraintTop_toBottomOf="@id/post" /> | ||
|
||
<TextView | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:text="Hello World!" | ||
app:layout_constraintBottom_toBottomOf="parent" | ||
app:layout_constraintLeft_toLeftOf="parent" | ||
app:layout_constraintRight_toRightOf="parent" | ||
app:layout_constraintTop_toTopOf="parent" /> | ||
<Button | ||
android:id="@+id/post_orderly" | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:text="post_orderly" | ||
app:layout_constraintTop_toBottomOf="@id/post_delay" /> | ||
|
||
<Button | ||
android:id="@+id/observe" | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:text="observe" | ||
app:layout_constraintTop_toBottomOf="@id/post_orderly" /> | ||
|
||
<Button | ||
android:id="@+id/observe_sticky" | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:text="observe_sticky" | ||
app:layout_constraintTop_toBottomOf="@id/observe" /> | ||
|
||
<Button | ||
android:id="@+id/observe_forever" | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:text="observe_forever" | ||
app:layout_constraintTop_toBottomOf="@id/observe_sticky" /> | ||
|
||
<Button | ||
android:id="@+id/observe_sticky_forever" | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:text="observe_sticky_forever" | ||
app:layout_constraintTop_toBottomOf="@id/observe_forever" /> | ||
</androidx.constraintlayout.widget.ConstraintLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
apply plugin: 'com.android.library' | ||
|
||
android { | ||
compileSdkVersion 29 | ||
buildToolsVersion "29.0.2" | ||
|
||
|
||
defaultConfig { | ||
minSdkVersion 16 | ||
targetSdkVersion 29 | ||
versionCode 1 | ||
versionName "1.0" | ||
|
||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
|
||
} | ||
|
||
buildTypes { | ||
release { | ||
minifyEnabled false | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
} | ||
} | ||
|
||
compileOptions { | ||
sourceCompatibility JavaVersion.VERSION_1_8 | ||
targetCompatibility JavaVersion.VERSION_1_8 | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation fileTree(dir: 'libs', include: ['*.jar']) | ||
|
||
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0" | ||
implementation 'androidx.appcompat:appcompat:1.0.2' | ||
testImplementation 'junit:junit:4.12' | ||
androidTestImplementation 'androidx.test:runner:1.2.0' | ||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="com.hhh.liveeventbus" /> |
129 changes: 129 additions & 0 deletions
129
liveeventbus/src/main/java/com/hhh/liveeventbus/LiveEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package com.hhh.liveeventbus; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import android.os.Handler; | ||
import android.os.Looper; | ||
|
||
import androidx.annotation.MainThread; | ||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.lifecycle.LifecycleOwner; | ||
import androidx.lifecycle.Observer; | ||
|
||
class LiveEvent<T> implements Observable<T> { | ||
|
||
private static final Handler HANDLER = new Handler(Looper.getMainLooper()); | ||
private final LiveEventData<T> mLiveData = new LiveEventData<>(); | ||
private final Map<Observer, ObserverWrapper<T>> mObserverMap = new HashMap<>(); | ||
|
||
private static boolean isMainThread() { | ||
return Looper.getMainLooper().getThread() == Thread.currentThread(); | ||
} | ||
|
||
@Override | ||
public void post(@Nullable T value) { | ||
if (isMainThread()) { | ||
postInternal(value); | ||
} else { | ||
HANDLER.post(() -> postInternal(value)); | ||
} | ||
} | ||
|
||
@Override | ||
public void postDelay(@Nullable T value, long delay) { | ||
HANDLER.postDelayed(() -> postInternal(value), delay); | ||
} | ||
|
||
@Override | ||
public void postOrderly(@Nullable T value) { | ||
HANDLER.post(() -> postInternal(value)); | ||
} | ||
|
||
@Override | ||
public void observe(@NonNull final LifecycleOwner owner, @NonNull final Observer<T> observer) { | ||
if (isMainThread()) { | ||
observeInternal(owner, observer); | ||
} else { | ||
HANDLER.post(() -> observeInternal(owner, observer)); | ||
} | ||
} | ||
|
||
@Override | ||
public void observeSticky(@NonNull final LifecycleOwner owner, | ||
@NonNull final Observer<T> observer) { | ||
if (isMainThread()) { | ||
observeStickyInternal(owner, observer); | ||
} else { | ||
HANDLER.post(() -> observeStickyInternal(owner, observer)); | ||
} | ||
} | ||
|
||
@Override | ||
public void observeForever(@NonNull final Observer<T> observer) { | ||
if (isMainThread()) { | ||
observeForeverInternal(observer); | ||
} else { | ||
HANDLER.post(() -> observeForeverInternal(observer)); | ||
} | ||
} | ||
|
||
@Override | ||
public void observeStickyForever(@NonNull final Observer<T> observer) { | ||
if (isMainThread()) { | ||
observeStickyForeverInternal(observer); | ||
} else { | ||
HANDLER.post(() -> observeStickyForeverInternal(observer)); | ||
} | ||
} | ||
|
||
@Override | ||
public void removeObserver(@NonNull final Observer<T> observer) { | ||
if (isMainThread()) { | ||
removeObserverInternal(observer); | ||
} else { | ||
HANDLER.post(() -> removeObserverInternal(observer)); | ||
} | ||
} | ||
|
||
@MainThread | ||
private void postInternal(T value) { | ||
mLiveData.setValue(value); | ||
} | ||
|
||
@MainThread | ||
private void observeInternal(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) { | ||
ObserverWrapper<T> observerWrapper = new ObserverWrapper<>(observer); | ||
observerWrapper.mPreventNextEvent = mLiveData.getVersion() > LiveEventData.START_VERSION; | ||
mLiveData.observe(owner, observerWrapper); | ||
} | ||
|
||
@MainThread | ||
private void observeStickyInternal(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) { | ||
mLiveData.observe(owner, new ObserverWrapper<>(observer)); | ||
} | ||
|
||
@MainThread | ||
private void observeForeverInternal(@NonNull Observer<T> observer) { | ||
ObserverWrapper<T> observerWrapper = new ObserverWrapper<>(observer); | ||
observerWrapper.mPreventNextEvent = mLiveData.getVersion() > LiveEventData.START_VERSION; | ||
mObserverMap.put(observer, observerWrapper); | ||
mLiveData.observeForever(observerWrapper); | ||
} | ||
|
||
@MainThread | ||
private void observeStickyForeverInternal(@NonNull Observer<T> observer) { | ||
ObserverWrapper<T> observerWrapper = new ObserverWrapper<>(observer); | ||
mObserverMap.put(observer, observerWrapper); | ||
mLiveData.observeForever(observerWrapper); | ||
} | ||
|
||
@MainThread | ||
private void removeObserverInternal(@NonNull Observer<T> observer) { | ||
if (mObserverMap.containsKey(observer)) { | ||
observer = mObserverMap.remove(observer); | ||
} | ||
mLiveData.removeObserver(observer); | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
liveeventbus/src/main/java/com/hhh/liveeventbus/LiveEventBus.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.hhh.liveeventbus; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import androidx.annotation.MainThread; | ||
import androidx.annotation.NonNull; | ||
|
||
public class LiveEventBus { | ||
|
||
private static final LiveEventBus LIVE_EVENT_BUS = new LiveEventBus(); | ||
|
||
private final Map<String, LiveEvent<Object>> mEventMap = new HashMap<>(); | ||
|
||
private LiveEventBus() {} | ||
|
||
@NonNull | ||
public static LiveEventBus getInstance() { | ||
return LIVE_EVENT_BUS; | ||
} | ||
|
||
@NonNull | ||
@MainThread | ||
public <T> Observable<T> with(@NonNull Class<T> type) { | ||
return with(type.getName(), type); | ||
} | ||
|
||
/** | ||
* 之所以要求在主线程,是不想加锁,只要不是高并发,在子线程也不会有问题 | ||
*/ | ||
@NonNull | ||
@MainThread | ||
public <T> Observable<T> with(@NonNull String key, @NonNull Class<T> type) { | ||
if (!mEventMap.containsKey(key)) { | ||
mEventMap.put(key, new LiveEvent<>()); | ||
} | ||
return (Observable<T>) mEventMap.get(key); | ||
} | ||
} |
Oops, something went wrong.