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.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
@ -2,6 +2,7 @@ package org.mian.gitnex.activities;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ArrayAdapter;
|
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.api.UserAccountsApi;
|
||||||
import org.mian.gitnex.database.models.UserAccount;
|
import org.mian.gitnex.database.models.UserAccount;
|
||||||
import org.mian.gitnex.helpers.AppUtil;
|
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.PathsHelper;
|
||||||
import org.mian.gitnex.helpers.TinyDB;
|
import org.mian.gitnex.helpers.TinyDB;
|
||||||
import org.mian.gitnex.helpers.Toasty;
|
import org.mian.gitnex.helpers.Toasty;
|
||||||
@ -63,7 +64,7 @@ public class LoginActivity extends BaseActivity {
|
|||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
NetworkObserver networkMonitor = new NetworkObserver(ctx);
|
NetworkStatusObserver networkStatusObserver = NetworkStatusObserver.get(ctx);
|
||||||
|
|
||||||
loginButton = findViewById(R.id.login_button);
|
loginButton = findViewById(R.id.login_button);
|
||||||
instanceUrlET = findViewById(R.id.instance_url);
|
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());
|
ArrayAdapter<Protocol> adapterProtocols = new ArrayAdapter<>(LoginActivity.this, R.layout.list_spinner_items, Protocol.values());
|
||||||
|
|
||||||
protocolSpinner.setAdapter(adapterProtocols);
|
protocolSpinner.setAdapter(adapterProtocols);
|
||||||
|
protocolSpinner.setSelection(0);
|
||||||
protocolSpinner.setOnItemClickListener((parent, view, position, id) -> {
|
protocolSpinner.setOnItemClickListener((parent, view, position, id) -> {
|
||||||
|
|
||||||
selectedProtocol = String.valueOf(parent.getItemAtPosition(position));
|
selectedProtocol = String.valueOf(parent.getItemAtPosition(position));
|
||||||
@ -115,18 +116,24 @@ public class LoginActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
networkMonitor.onInternetStateListener(isAvailable -> {
|
Handler handler = new Handler(getMainLooper());
|
||||||
|
|
||||||
if(isAvailable) {
|
networkStatusObserver.registerNetworkStatusListener(hasNetworkConnection -> {
|
||||||
|
|
||||||
enableProcessButton();
|
handler.post(() -> {
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
disableProcessButton();
|
if(hasNetworkConnection) {
|
||||||
loginButton.setText(getResources().getString(R.string.btnLogin));
|
|
||||||
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
enableProcessButton();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
disableProcessButton();
|
||||||
|
loginButton.setText(getResources().getString(R.string.btnLogin));
|
||||||
|
Toasty.error(ctx, getResources().getString(R.string.checkNetConnection));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
loadDefaults();
|
loadDefaults();
|
||||||
@ -267,8 +274,10 @@ public class LoginActivity extends BaseActivity {
|
|||||||
|
|
||||||
if(gitea_version.less(getString(R.string.versionLow))) {
|
if(gitea_version.less(getString(R.string.versionLow))) {
|
||||||
|
|
||||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx).setTitle(getString(R.string.versionAlertDialogHeader))
|
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ctx)
|
||||||
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion())).setIcon(R.drawable.ic_warning)
|
.setTitle(getString(R.string.versionAlertDialogHeader))
|
||||||
|
.setMessage(getResources().getString(R.string.versionUnsupportedOld, version.getVersion()))
|
||||||
|
.setIcon(R.drawable.ic_warning)
|
||||||
.setCancelable(true);
|
.setCancelable(true);
|
||||||
|
|
||||||
alertDialogBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
|
alertDialogBuilder.setNegativeButton(getString(R.string.cancelButton), (dialog, which) -> {
|
||||||
|
@ -36,8 +36,6 @@ public class RetrofitClient {
|
|||||||
|
|
||||||
TinyDB tinyDB = TinyDB.getInstance(context);
|
TinyDB tinyDB = TinyDB.getInstance(context);
|
||||||
|
|
||||||
final boolean connToInternet = AppUtil.hasNetworkConnection(context);
|
|
||||||
|
|
||||||
int cacheSize = FilesData.returnOnlyNumber(tinyDB.getString("cacheSizeStr")) * 1024 * 1024;
|
int cacheSize = FilesData.returnOnlyNumber(tinyDB.getString("cacheSizeStr")) * 1024 * 1024;
|
||||||
Cache cache = new Cache(new File(context.getCacheDir(), "responses"), cacheSize);
|
Cache cache = new Cache(new File(context.getCacheDir(), "responses"), cacheSize);
|
||||||
|
|
||||||
@ -59,7 +57,7 @@ public class RetrofitClient {
|
|||||||
|
|
||||||
Request request = chain.request();
|
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, max-age=" + 60).build() :
|
||||||
request.newBuilder().header("Cache-Control", "public, only-if-cached, max-stale=" + 60 * 60 * 24 * 30).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.pm.PackageManager;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.net.ConnectivityManager;
|
|
||||||
import android.net.NetworkInfo;
|
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import androidx.annotation.ColorInt;
|
import androidx.annotation.ColorInt;
|
||||||
|
import androidx.core.content.pm.PackageInfoCompat;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@ -34,32 +33,14 @@ public class AppUtil {
|
|||||||
|
|
||||||
public static boolean hasNetworkConnection(Context context) {
|
public static boolean hasNetworkConnection(Context context) {
|
||||||
|
|
||||||
boolean haveConnectedWifi = false;
|
return NetworkStatusObserver.get(context).hasNetworkConnection();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getAppBuildNo(Context context) {
|
public static int getAppBuildNo(Context context) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
|
||||||
return packageInfo.versionCode;
|
return (int) PackageInfoCompat.getLongVersionCode(packageInfo);
|
||||||
}
|
}
|
||||||
catch(PackageManager.NameNotFoundException e) {
|
catch(PackageManager.NameNotFoundException e) {
|
||||||
throw new RuntimeException("Could not get package name: " + 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.Bitmap.CompressFormat;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -25,7 +24,7 @@ public class TinyDB {
|
|||||||
private String lastImagePath = "";
|
private String lastImagePath = "";
|
||||||
|
|
||||||
private TinyDB(Context appContext) {
|
private TinyDB(Context appContext) {
|
||||||
preferences = PreferenceManager.getDefaultSharedPreferences(appContext);
|
preferences = appContext.getSharedPreferences(appContext.getPackageName() + "_preferences", Context.MODE_PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized TinyDB getInstance(Context context) {
|
public static synchronized TinyDB getInstance(Context context) {
|
||||||
|
Loading…
Reference in New Issue
Block a user