mirror of
https://codeberg.org/gitnex/GitNex.git
synced 2024-12-26 16:04:07 +08:00
Rewriting deprecated code and improving offline mode. (#800)
Moving UI-related code to message queue of main thread. Removing NetworkObserver in favor of NetworkStatusObserver Some fixes. Removing deprecated PreferenceManager. Fixing crash. Merge branch 'master' of https://codeberg.org/gitnex/GitNex into fix-performance-regression Conflicts: app/src/main/java/org/mian/gitnex/clients/RetrofitClient.java Rewriting deprecated code. Improving degraded performance due to unnecessary object allocation. Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/800 Reviewed-by: M M Arif <mmarif@noreply.codeberg.org> Co-Authored-By: opyale <opyale@noreply.codeberg.org> Co-Committed-By: opyale <opyale@noreply.codeberg.org>
This commit is contained in:
parent
5d2bb02b2d
commit
b75bf84d43
@ -6,6 +6,7 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
@ -2,6 +2,7 @@ package org.mian.gitnex.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
@ -17,7 +18,7 @@ import org.mian.gitnex.clients.RetrofitClient;
|
||||
import org.mian.gitnex.database.api.UserAccountsApi;
|
||||
import org.mian.gitnex.database.models.UserAccount;
|
||||
import org.mian.gitnex.helpers.AppUtil;
|
||||
import org.mian.gitnex.helpers.NetworkObserver;
|
||||
import org.mian.gitnex.helpers.NetworkStatusObserver;
|
||||
import org.mian.gitnex.helpers.PathsHelper;
|
||||
import org.mian.gitnex.helpers.TinyDB;
|
||||
import org.mian.gitnex.helpers.Toasty;
|
||||
@ -63,7 +64,7 @@ public class LoginActivity extends BaseActivity {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
NetworkObserver networkMonitor = new NetworkObserver(ctx);
|
||||
NetworkStatusObserver networkStatusObserver = NetworkStatusObserver.get(ctx);
|
||||
|
||||
loginButton = findViewById(R.id.login_button);
|
||||
instanceUrlET = findViewById(R.id.instance_url);
|
||||
@ -79,7 +80,7 @@ public class LoginActivity extends BaseActivity {
|
||||
ArrayAdapter<Protocol> adapterProtocols = new ArrayAdapter<>(LoginActivity.this, R.layout.list_spinner_items, Protocol.values());
|
||||
|
||||
protocolSpinner.setAdapter(adapterProtocols);
|
||||
|
||||
protocolSpinner.setSelection(0);
|
||||
protocolSpinner.setOnItemClickListener((parent, view, position, id) -> {
|
||||
|
||||
selectedProtocol = String.valueOf(parent.getItemAtPosition(position));
|
||||
@ -115,9 +116,13 @@ public class LoginActivity extends BaseActivity {
|
||||
}
|
||||
});
|
||||
|
||||
networkMonitor.onInternetStateListener(isAvailable -> {
|
||||
Handler handler = new Handler(getMainLooper());
|
||||
|
||||
if(isAvailable) {
|
||||
networkStatusObserver.registerNetworkStatusListener(hasNetworkConnection -> {
|
||||
|
||||
handler.post(() -> {
|
||||
|
||||
if(hasNetworkConnection) {
|
||||
|
||||
enableProcessButton();
|
||||
}
|
||||
@ -127,6 +132,8 @@ public class LoginActivity extends BaseActivity {
|
||||
loginButton.setText(getResources().getString(R.string.btnLogin));
|
||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
loadDefaults();
|
||||
@ -267,8 +274,10 @@ public class LoginActivity extends BaseActivity {
|
||||
|
||||
if(gitea_version.less(getString(R.string.versionLow))) {
|
||||
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx).setTitle(getString(R.string.versionAlertDialogHeader))
|
||||
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())).setIcon(R.drawable.ic_warning)
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx)
|
||||
.setTitle(getString(R.string.versionAlertDialogHeader))
|
||||
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion()))
|
||||
.setIcon(R.drawable.ic_warning)
|
||||
.setCancelable(true);
|
||||
|
||||
alertDialogBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
|
||||
|
@ -36,8 +36,6 @@ public class RetrofitClient {
|
||||
|
||||
TinyDB tinyDB = TinyDB.getInstance(context);
|
||||
|
||||
final boolean connToInternet = AppUtil.hasNetworkConnection(context);
|
||||
|
||||
int cacheSize = FilesData.returnOnlyNumber(tinyDB.getString("cacheSizeStr")) * 1024 * 1024;
|
||||
Cache cache = new Cache(new File(context.getCacheDir(), "responses"), cacheSize);
|
||||
|
||||
@ -59,7 +57,7 @@ public class RetrofitClient {
|
||||
|
||||
Request request = chain.request();
|
||||
|
||||
request = connToInternet ?
|
||||
request = AppUtil.hasNetworkConnection(context) ?
|
||||
request.newBuilder().header("Cache-Control", "public, max-age=" + 60).build() :
|
||||
request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).build();
|
||||
|
||||
|
@ -5,13 +5,12 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.util.Base64;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.core.content.pm.PackageInfoCompat;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -34,32 +33,14 @@ public class AppUtil {
|
||||
|
||||
public static boolean hasNetworkConnection(Context context) {
|
||||
|
||||
boolean haveConnectedWifi = false;
|
||||
boolean haveConnectedMobile = false;
|
||||
|
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
assert cm != null;
|
||||
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
|
||||
for(NetworkInfo ni : netInfo) {
|
||||
if(ni.getTypeName().equalsIgnoreCase("WIFI")) {
|
||||
if(ni.isConnected()) {
|
||||
haveConnectedWifi = true;
|
||||
}
|
||||
}
|
||||
if(ni.getTypeName().equalsIgnoreCase("MOBILE")) {
|
||||
if(ni.isConnected()) {
|
||||
haveConnectedMobile = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return haveConnectedWifi || haveConnectedMobile;
|
||||
return NetworkStatusObserver.get(context).hasNetworkConnection();
|
||||
}
|
||||
|
||||
public static int getAppBuildNo(Context context) {
|
||||
|
||||
try {
|
||||
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||
return packageInfo.versionCode;
|
||||
return (int) PackageInfoCompat.getLongVersionCode(packageInfo);
|
||||
}
|
||||
catch(PackageManager.NameNotFoundException e) {
|
||||
throw new RuntimeException("Could not get package name: " + e);
|
||||
|
@ -1,82 +0,0 @@
|
||||
package org.mian.gitnex.helpers;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
|
||||
/**
|
||||
* Author M M Arif
|
||||
*/
|
||||
|
||||
public class NetworkObserver implements LifecycleObserver {
|
||||
|
||||
private ConnectivityManager mConnectivityMgr;
|
||||
private Context mContext;
|
||||
private NetworkStateReceiver mNetworkStateReceiver;
|
||||
|
||||
public interface ConnectionStateListener {
|
||||
void onAvailable(boolean isAvailable);
|
||||
}
|
||||
|
||||
public NetworkObserver(Context context) {
|
||||
mContext = context;
|
||||
mConnectivityMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
((AppCompatActivity) mContext).getLifecycle().addObserver(this);
|
||||
}
|
||||
|
||||
|
||||
public void onInternetStateListener(ConnectionStateListener listener) {
|
||||
|
||||
mNetworkStateReceiver = new NetworkStateReceiver(listener);
|
||||
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
mContext.registerReceiver(mNetworkStateReceiver, intentFilter);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
|
||||
public void onDestroy() {
|
||||
|
||||
((AppCompatActivity) mContext).getLifecycle().removeObserver(this);
|
||||
|
||||
if (mNetworkStateReceiver != null) {
|
||||
mContext.unregisterReceiver(mNetworkStateReceiver);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class NetworkStateReceiver extends BroadcastReceiver {
|
||||
|
||||
ConnectionStateListener mListener;
|
||||
|
||||
public NetworkStateReceiver(ConnectionStateListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getExtras() != null) {
|
||||
NetworkInfo activeNetworkInfo = mConnectivityMgr.getActiveNetworkInfo();
|
||||
|
||||
if (activeNetworkInfo != null && activeNetworkInfo.getState() == NetworkInfo.State.CONNECTED) {
|
||||
|
||||
mListener.onAvailable(true); // connected
|
||||
|
||||
} else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
|
||||
|
||||
mListener.onAvailable(false); // disconnected
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package org.mian.gitnex.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* @author opyale
|
||||
*/
|
||||
public class NetworkStatusObserver {
|
||||
|
||||
private static NetworkStatusObserver networkStatusObserver;
|
||||
|
||||
private final AtomicBoolean hasNetworkConnection = new AtomicBoolean(false);
|
||||
private final List<NetworkStatusListener> networkStatusListeners = new ArrayList<>();
|
||||
|
||||
private final Object mutex = new Object();
|
||||
private boolean hasInitialized = false;
|
||||
|
||||
private NetworkStatusObserver(Context context) {
|
||||
|
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
NetworkRequest networkRequest = new NetworkRequest.Builder()
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
|
||||
.build();
|
||||
|
||||
cm.requestNetwork(networkRequest, new ConnectivityManager.NetworkCallback() {
|
||||
|
||||
@Override
|
||||
public void onAvailable(@NonNull Network network) {
|
||||
hasNetworkConnection.set(true);
|
||||
networkStatusChanged();
|
||||
checkInitialized();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLost(@NonNull Network network) {
|
||||
hasNetworkConnection.set(false);
|
||||
networkStatusChanged();
|
||||
checkInitialized();
|
||||
}
|
||||
|
||||
private void checkInitialized() {
|
||||
|
||||
if(!hasInitialized) {
|
||||
hasInitialized = true;
|
||||
synchronized(mutex) {
|
||||
mutex.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
synchronized(mutex) {
|
||||
try {
|
||||
// This is actually not the recommended way to do this, but there
|
||||
// is no other option besides upgrading to API level 26
|
||||
// in order to use the built-in timeout functionality of {@code requestNetwork()}
|
||||
// which in turn gives us access to {@code onUnavailable()} .
|
||||
mutex.wait(5);
|
||||
} catch(InterruptedException ignored) {}
|
||||
}
|
||||
|
||||
if(!hasInitialized) {
|
||||
hasInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void networkStatusChanged() {
|
||||
boolean hasNetworkConnection = hasNetworkConnection();
|
||||
|
||||
for(NetworkStatusListener networkStatusListener : networkStatusListeners) {
|
||||
networkStatusListener.onNetworkStatusChanged(hasNetworkConnection);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNetworkConnection() {
|
||||
return hasNetworkConnection.get();
|
||||
}
|
||||
|
||||
public void registerNetworkStatusListener(NetworkStatusListener networkStatusListener) {
|
||||
networkStatusListeners.add(networkStatusListener);
|
||||
networkStatusListener.onNetworkStatusChanged(hasNetworkConnection());
|
||||
}
|
||||
|
||||
public void unregisterNetworkStatusListener(NetworkStatusListener networkStatusListener) {
|
||||
networkStatusListeners.remove(networkStatusListener);
|
||||
}
|
||||
|
||||
public interface NetworkStatusListener { void onNetworkStatusChanged(boolean hasNetworkConnection); }
|
||||
|
||||
public static NetworkStatusObserver get(Context context) {
|
||||
if(networkStatusObserver == null) {
|
||||
networkStatusObserver = new NetworkStatusObserver(context);
|
||||
}
|
||||
|
||||
return networkStatusObserver;
|
||||
}
|
||||
|
||||
}
|
@ -6,7 +6,6 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import java.io.File;
|
||||
@ -25,7 +24,7 @@ public class TinyDB {
|
||||
private String lastImagePath = "";
|
||||
|
||||
private TinyDB(Context appContext) {
|
||||
preferences = PreferenceManager.getDefaultSharedPreferences(appContext);
|
||||
preferences = appContext.getSharedPreferences(appContext.getPackageName() + "_preferences", Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public static synchronized TinyDB getInstance(Context context) {
|
||||
|
Loading…
Reference in New Issue
Block a user