Skip to content

Commit 2e96b65

Browse files
committed
Replaced Icepick with Bridge and Android-State
* IcePick fails on Java 21 (default in Android Studio 2024.2) * Bridge is the most modern alternative that is currently available. It is backed by ``Android-State`` and can be configured with various frameworks * In the long term this should be replaced with something better
1 parent 2482615 commit 2e96b65

30 files changed

+171
-104
lines changed

app/build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ ext {
113113
androidxRoomVersion = '2.6.1'
114114
androidxWorkVersion = '2.8.1'
115115

116-
icepickVersion = '3.2.0'
116+
stateSaverVersion = '1.4.1'
117117
exoPlayerVersion = '2.18.7'
118118
googleAutoServiceVersion = '1.1.1'
119119
groupieVersion = '2.10.1'
@@ -236,8 +236,9 @@ dependencies {
236236

237237
/** Third-party libraries **/
238238
// Instance state boilerplate elimination
239-
implementation "frankiesardo:icepick:${icepickVersion}"
240-
kapt "frankiesardo:icepick-processor:${icepickVersion}"
239+
implementation 'com.github.livefront:bridge:v2.0.2'
240+
implementation "com.evernote:android-state:$stateSaverVersion"
241+
kapt "com.evernote:android-state-processor:$stateSaverVersion"
241242

242243
// HTML parser
243244
implementation "org.jsoup:jsoup:1.17.2"

app/proguard-rules.pro

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,6 @@
1313
## Rules for ExoPlayer
1414
-keep class com.google.android.exoplayer2.** { *; }
1515

16-
## Rules for Icepick. Copy pasted from https://github.com/frankiesardo/icepick
17-
-dontwarn icepick.**
18-
-keep class icepick.** { *; }
19-
-keep class **$$Icepick { *; }
20-
-keepclasseswithmembernames class * {
21-
@icepick.* <fields>;
22-
}
23-
-keepnames class * { @icepick.State *;}
24-
2516
## Rules for OkHttp. Copy pasted from https://github.com/square/okhttp
2617
-dontwarn okhttp3.**
2718
-dontwarn okio.**

app/src/main/java/org/schabi/newpipe/App.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@
1919
import org.schabi.newpipe.extractor.downloader.Downloader;
2020
import org.schabi.newpipe.ktx.ExceptionUtils;
2121
import org.schabi.newpipe.settings.NewPipeSettings;
22+
import org.schabi.newpipe.util.BridgeStateSaverInitializer;
2223
import org.schabi.newpipe.util.Localization;
23-
import org.schabi.newpipe.util.image.ImageStrategy;
24-
import org.schabi.newpipe.util.image.PicassoHelper;
2524
import org.schabi.newpipe.util.ServiceHelper;
2625
import org.schabi.newpipe.util.StateSaver;
26+
import org.schabi.newpipe.util.image.ImageStrategy;
27+
import org.schabi.newpipe.util.image.PicassoHelper;
2728
import org.schabi.newpipe.util.image.PreferredImageQuality;
2829

2930
import java.io.IOException;
@@ -101,6 +102,7 @@ public void onCreate() {
101102
Localization.getPreferredContentCountry(this));
102103
Localization.initPrettyTime(Localization.resolvePrettyTime(getApplicationContext()));
103104

105+
BridgeStateSaverInitializer.init(this);
104106
StateSaver.init(this);
105107
initNotificationChannels();
106108

app/src/main/java/org/schabi/newpipe/BaseFragment.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
import androidx.fragment.app.Fragment;
1111
import androidx.fragment.app.FragmentManager;
1212

13-
import icepick.Icepick;
14-
import icepick.State;
13+
import com.evernote.android.state.State;
14+
import com.livefront.bridge.Bridge;
15+
1516

1617
public abstract class BaseFragment extends Fragment {
1718
protected final String TAG = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
@@ -48,7 +49,7 @@ public void onCreate(final Bundle savedInstanceState) {
4849
+ "savedInstanceState = [" + savedInstanceState + "]");
4950
}
5051
super.onCreate(savedInstanceState);
51-
Icepick.restoreInstanceState(this, savedInstanceState);
52+
Bridge.restoreInstanceState(this, savedInstanceState);
5253
if (savedInstanceState != null) {
5354
onRestoreInstanceState(savedInstanceState);
5455
}
@@ -70,7 +71,7 @@ public void onViewCreated(@NonNull final View rootView, final Bundle savedInstan
7071
@Override
7172
public void onSaveInstanceState(@NonNull final Bundle outState) {
7273
super.onSaveInstanceState(outState);
73-
Icepick.saveInstanceState(this, outState);
74+
Bridge.saveInstanceState(this, outState);
7475
}
7576

7677
protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {

app/src/main/java/org/schabi/newpipe/RouterActivity.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
import androidx.lifecycle.LifecycleOwner;
4242
import androidx.preference.PreferenceManager;
4343

44+
import com.evernote.android.state.State;
45+
import com.livefront.bridge.Bridge;
46+
4447
import org.schabi.newpipe.database.stream.model.StreamEntity;
4548
import org.schabi.newpipe.databinding.ListRadioIconItemBinding;
4649
import org.schabi.newpipe.databinding.SingleChoiceDialogViewBinding;
@@ -98,8 +101,6 @@
98101
import java.util.Optional;
99102
import java.util.function.Consumer;
100103

101-
import icepick.Icepick;
102-
import icepick.State;
103104
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
104105
import io.reactivex.rxjava3.core.Observable;
105106
import io.reactivex.rxjava3.core.Single;
@@ -152,7 +153,7 @@ protected void onCreate(final Bundle savedInstanceState) {
152153
getWindow().setAttributes(params);
153154

154155
super.onCreate(savedInstanceState);
155-
Icepick.restoreInstanceState(this, savedInstanceState);
156+
Bridge.restoreInstanceState(this, savedInstanceState);
156157

157158
// FragmentManager will take care to recreate (Playlist|Download)Dialog when screen rotates
158159
// We used to .setOnDismissListener(dialog -> finish()); when creating these DialogFragments
@@ -197,7 +198,7 @@ protected void onStop() {
197198
@Override
198199
protected void onSaveInstanceState(@NonNull final Bundle outState) {
199200
super.onSaveInstanceState(outState);
200-
Icepick.saveInstanceState(this, outState);
201+
Bridge.saveInstanceState(this, outState);
201202
}
202203

203204
@Override

app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,12 @@ class AboutActivity : AppCompatActivity() {
138138
"https://github.com/lisawray/groupie", StandardLicenses.MIT
139139
),
140140
SoftwareComponent(
141-
"Icepick", "2015", "Frankie Sardo",
142-
"https://github.com/frankiesardo/icepick", StandardLicenses.EPL1
141+
"Android-State", "2018", "Evernote",
142+
"https://github.com/Evernote/android-state", StandardLicenses.EPL1
143+
),
144+
SoftwareComponent(
145+
"Bridge", "2021", "Livefront",
146+
"https://github.com/livefront/bridge", StandardLicenses.APACHE2
143147
),
144148
SoftwareComponent(
145149
"Jsoup", "2009 - 2020", "Jonathan Hedley",

app/src/main/java/org/schabi/newpipe/download/DownloadDialog.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import androidx.fragment.app.DialogFragment;
4040
import androidx.preference.PreferenceManager;
4141

42+
import com.evernote.android.state.State;
43+
import com.livefront.bridge.Bridge;
4244
import com.nononsenseapps.filepicker.Utils;
4345

4446
import org.schabi.newpipe.MainActivity;
@@ -59,6 +61,8 @@
5961
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
6062
import org.schabi.newpipe.streams.io.StoredDirectoryHelper;
6163
import org.schabi.newpipe.streams.io.StoredFileHelper;
64+
import org.schabi.newpipe.util.AudioTrackAdapter;
65+
import org.schabi.newpipe.util.AudioTrackAdapter.AudioTracksWrapper;
6266
import org.schabi.newpipe.util.FilePickerActivityHelper;
6367
import org.schabi.newpipe.util.FilenameUtils;
6468
import org.schabi.newpipe.util.ListHelper;
@@ -67,8 +71,6 @@
6771
import org.schabi.newpipe.util.SimpleOnSeekBarChangeListener;
6872
import org.schabi.newpipe.util.StreamItemAdapter;
6973
import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper;
70-
import org.schabi.newpipe.util.AudioTrackAdapter;
71-
import org.schabi.newpipe.util.AudioTrackAdapter.AudioTracksWrapper;
7274
import org.schabi.newpipe.util.ThemeHelper;
7375

7476
import java.io.File;
@@ -79,8 +81,6 @@
7981
import java.util.Objects;
8082
import java.util.Optional;
8183

82-
import icepick.Icepick;
83-
import icepick.State;
8484
import io.reactivex.rxjava3.disposables.CompositeDisposable;
8585
import us.shandian.giga.get.MissionRecoveryInfo;
8686
import us.shandian.giga.postprocessing.Postprocessing;
@@ -214,7 +214,7 @@ public void onCreate(@Nullable final Bundle savedInstanceState) {
214214
context = getContext();
215215

216216
setStyle(STYLE_NO_TITLE, ThemeHelper.getDialogTheme(context));
217-
Icepick.restoreInstanceState(this, savedInstanceState);
217+
Bridge.restoreInstanceState(this, savedInstanceState);
218218

219219
this.audioTrackAdapter = new AudioTrackAdapter(wrappedAudioTracks);
220220
this.subtitleStreamsAdapter = new StreamItemAdapter<>(wrappedSubtitleStreams);
@@ -372,7 +372,7 @@ public void onDestroyView() {
372372
@Override
373373
public void onSaveInstanceState(@NonNull final Bundle outState) {
374374
super.onSaveInstanceState(outState);
375-
Icepick.saveInstanceState(this, outState);
375+
Bridge.saveInstanceState(this, outState);
376376
}
377377

378378

app/src/main/java/org/schabi/newpipe/fragments/BaseStateFragment.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import androidx.annotation.StringRes;
1414
import androidx.fragment.app.Fragment;
1515

16+
import com.evernote.android.state.State;
17+
1618
import org.schabi.newpipe.BaseFragment;
1719
import org.schabi.newpipe.R;
1820
import org.schabi.newpipe.error.ErrorInfo;
@@ -22,8 +24,6 @@
2224

2325
import java.util.concurrent.atomic.AtomicBoolean;
2426

25-
import icepick.State;
26-
2727
public abstract class BaseStateFragment<I> extends BaseFragment implements ViewContract<I> {
2828
@State
2929
protected AtomicBoolean wasLoading = new AtomicBoolean();
@@ -134,6 +134,7 @@ public void hideLoading() {
134134
hideErrorPanel();
135135
}
136136

137+
@Override
137138
public void showEmptyState() {
138139
isLoading.set(false);
139140
if (emptyStateView != null) {

app/src/main/java/org/schabi/newpipe/fragments/detail/DescriptionFragment.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import androidx.annotation.Nullable;
1212
import androidx.annotation.StringRes;
1313

14+
import com.evernote.android.state.State;
15+
1416
import org.schabi.newpipe.R;
1517
import org.schabi.newpipe.extractor.StreamingService;
1618
import org.schabi.newpipe.extractor.stream.Description;
@@ -19,8 +21,6 @@
1921

2022
import java.util.List;
2123

22-
import icepick.State;
23-
2424
public class DescriptionFragment extends BaseDescriptionFragment {
2525

2626
@State
@@ -31,7 +31,7 @@ public DescriptionFragment(final StreamInfo streamInfo) {
3131
}
3232

3333
public DescriptionFragment() {
34-
// keep empty constructor for IcePick when resuming fragment from memory
34+
// keep empty constructor for State when resuming fragment from memory
3535
}
3636

3737

app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import androidx.fragment.app.Fragment;
5757
import androidx.preference.PreferenceManager;
5858

59+
import com.evernote.android.state.State;
5960
import com.google.android.exoplayer2.PlaybackException;
6061
import com.google.android.exoplayer2.PlaybackParameters;
6162
import com.google.android.material.appbar.AppBarLayout;
@@ -127,7 +128,6 @@
127128
import java.util.concurrent.TimeUnit;
128129
import java.util.function.Consumer;
129130

130-
import icepick.State;
131131
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
132132
import io.reactivex.rxjava3.disposables.CompositeDisposable;
133133
import io.reactivex.rxjava3.disposables.Disposable;

0 commit comments

Comments
 (0)