use AsyncTask with 5MB stack in lots of places
This commit is contained in:
parent
fae07ed716
commit
f8ea3cc77f
|
@ -17,8 +17,10 @@
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -28,15 +30,13 @@ import android.widget.TextView;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.service.MoneroHandlerThread;
|
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class GenerateReviewFragment extends Fragment {
|
public class GenerateReviewFragment extends Fragment {
|
||||||
static final String TAG = "GenerateReviewFragment";
|
static final String TAG = "GenerateReviewFragment";
|
||||||
static final public String VIEW_DETAILS = "details";
|
static final public String VIEW_TYPE_DETAILS = "details";
|
||||||
static final public String VIEW_ACCEPT = "accept";
|
static final public String VIEW_TYPE_ACCEPT = "accept";
|
||||||
static final public String VIEW_WALLET = "wallet";
|
static final public String VIEW_TYPE_WALLET = "wallet";
|
||||||
|
|
||||||
ProgressBar pbProgress;
|
ProgressBar pbProgress;
|
||||||
TextView tvWalletName;
|
TextView tvWalletName;
|
||||||
|
@ -76,16 +76,12 @@ public class GenerateReviewFragment extends Fragment {
|
||||||
|
|
||||||
showProgress();
|
showProgress();
|
||||||
|
|
||||||
Bundle b = getArguments();
|
Bundle args = getArguments();
|
||||||
String type = b.getString("type");
|
String path = args.getString("path");
|
||||||
if (!type.equals(VIEW_WALLET)) {
|
String password = args.getString("password");
|
||||||
String path = b.getString("path");
|
String type = args.getString("type");
|
||||||
String password = b.getString("password");
|
new AsyncShow().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR,
|
||||||
tvWalletName.setText(new File(path).getName());
|
path, password, type);
|
||||||
show(path, password, type);
|
|
||||||
} else {
|
|
||||||
show(walletCallback.getWallet(), null, type);
|
|
||||||
}
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,41 +92,65 @@ public class GenerateReviewFragment extends Fragment {
|
||||||
acceptCallback.onAccept(name, password);
|
acceptCallback.onAccept(name, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void show(final String walletPath, final String password, final String type) {
|
private class AsyncShow extends AsyncTask<String, Void, Boolean> {
|
||||||
new Thread(null,
|
String type;
|
||||||
new Runnable() {
|
String password;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
String address;
|
||||||
|
String seed;
|
||||||
|
String viewKey;
|
||||||
|
boolean isWatchOnly;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
protected Boolean doInBackground(String... params) {
|
||||||
final Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
if (params.length != 3) return false;
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
String walletPath = params[0];
|
||||||
public void run() {
|
password = params[1];
|
||||||
show(wallet, password, type);
|
type = params[2];
|
||||||
wallet.close();
|
|
||||||
|
Wallet wallet;
|
||||||
|
boolean closeWallet;
|
||||||
|
if (type.equals(GenerateReviewFragment.VIEW_TYPE_WALLET)) {
|
||||||
|
wallet = GenerateReviewFragment.this.walletCallback.getWallet();
|
||||||
|
closeWallet = false;
|
||||||
|
} else {
|
||||||
|
wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
||||||
|
closeWallet = true;
|
||||||
}
|
}
|
||||||
});
|
if (wallet.getStatus() != Wallet.Status.Status_Ok) return false;
|
||||||
}
|
name = wallet.getName();
|
||||||
}
|
address = wallet.getAddress();
|
||||||
, "DetailsReview", MoneroHandlerThread.THREAD_STACK_SIZE).start();
|
seed = wallet.getSeed();
|
||||||
|
viewKey = wallet.getSecretViewKey();
|
||||||
|
isWatchOnly = wallet.isWatchOnly();
|
||||||
|
if (closeWallet) wallet.close();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void show(final Wallet wallet, final String password, final String type) {
|
@Override
|
||||||
if (type.equals(GenerateReviewFragment.VIEW_ACCEPT)) {
|
protected void onPostExecute(Boolean result) {
|
||||||
|
super.onPostExecute(result);
|
||||||
|
if (result) {
|
||||||
|
if (type.equals(GenerateReviewFragment.VIEW_TYPE_ACCEPT)) {
|
||||||
tvWalletPassword.setText(password);
|
tvWalletPassword.setText(password);
|
||||||
bAccept.setVisibility(View.VISIBLE);
|
bAccept.setVisibility(View.VISIBLE);
|
||||||
bAccept.setEnabled(true);
|
bAccept.setEnabled(true);
|
||||||
}
|
}
|
||||||
tvWalletName.setText(wallet.getName());
|
tvWalletName.setText(name);
|
||||||
tvWalletAddress.setText(wallet.getAddress());
|
tvWalletAddress.setText(address);
|
||||||
tvWalletMnemonic.setText(wallet.getSeed());
|
tvWalletMnemonic.setText(seed);
|
||||||
tvWalletViewKey.setText(wallet.getSecretViewKey());
|
tvWalletViewKey.setText(viewKey);
|
||||||
String spend = wallet.isWatchOnly() ? "" : "not available - use seed for recovery";
|
String spend = isWatchOnly ? "" : "not available - use seed for recovery";
|
||||||
if (spend.length() > 0) { //TODO should be == 64, but spendkey is not in the API yet
|
if (spend.length() > 0) { //TODO should be == 64, but spendkey is not in the API yet
|
||||||
tvWalletSpendKey.setText(spend);
|
tvWalletSpendKey.setText(spend);
|
||||||
} else {
|
} else {
|
||||||
tvWalletSpendKey.setText(getString(R.string.generate_wallet_watchonly));
|
tvWalletSpendKey.setText(getString(R.string.generate_wallet_watchonly));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
hideProgress();
|
hideProgress();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GenerateReviewFragment.Listener acceptCallback = null;
|
GenerateReviewFragment.Listener acceptCallback = null;
|
||||||
GenerateReviewFragment.ListenerWithWallet walletCallback = null;
|
GenerateReviewFragment.ListenerWithWallet walletCallback = null;
|
||||||
|
@ -141,6 +161,7 @@ public class GenerateReviewFragment extends Fragment {
|
||||||
|
|
||||||
public interface ListenerWithWallet {
|
public interface ListenerWithWallet {
|
||||||
Wallet getWallet();
|
Wallet getWallet();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -121,7 +121,7 @@ public class LoginActivity extends AppCompatActivity
|
||||||
promptPassword(walletName, new PasswordAction() {
|
promptPassword(walletName, new PasswordAction() {
|
||||||
@Override
|
@Override
|
||||||
public void action(String walletName, String password) {
|
public void action(String walletName, String password) {
|
||||||
startDetails(walletFile, password, GenerateReviewFragment.VIEW_DETAILS);
|
startDetails(walletFile, password, GenerateReviewFragment.VIEW_TYPE_DETAILS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else { // this cannot really happen as we prefilter choices
|
} else { // this cannot really happen as we prefilter choices
|
||||||
|
@ -646,6 +646,7 @@ public class LoginActivity extends AppCompatActivity
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
static final String MNEMONIC_LANGUAGE = "English"; // see mnemonics/electrum-words.cpp for more
|
static final String MNEMONIC_LANGUAGE = "English"; // see mnemonics/electrum-words.cpp for more
|
||||||
|
|
||||||
|
// TODO make this an AsyncTask?
|
||||||
public void createWallet(final String name, final String password, final WalletCreator walletCreator) {
|
public void createWallet(final String name, final String password, final WalletCreator walletCreator) {
|
||||||
final GenerateFragment genFragment = (GenerateFragment)
|
final GenerateFragment genFragment = (GenerateFragment)
|
||||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||||
|
@ -666,7 +667,7 @@ public class LoginActivity extends AppCompatActivity
|
||||||
cacheFile.delete();
|
cacheFile.delete();
|
||||||
File keysFile = new File(newWalletFolder, name + ".keys");
|
File keysFile = new File(newWalletFolder, name + ".keys");
|
||||||
keysFile.delete();
|
keysFile.delete();
|
||||||
final File addressFile = new File(newWalletFolder, name + ".address.txt");
|
File addressFile = new File(newWalletFolder, name + ".address.txt");
|
||||||
addressFile.delete();
|
addressFile.delete();
|
||||||
|
|
||||||
if (cacheFile.exists() || keysFile.exists() || addressFile.exists()) {
|
if (cacheFile.exists() || keysFile.exists() || addressFile.exists()) {
|
||||||
|
@ -678,7 +679,7 @@ public class LoginActivity extends AppCompatActivity
|
||||||
File newWalletFile = new File(newWalletFolder, name);
|
File newWalletFile = new File(newWalletFolder, name);
|
||||||
boolean success = walletCreator.createWallet(newWalletFile, password);
|
boolean success = walletCreator.createWallet(newWalletFile, password);
|
||||||
if (success) {
|
if (success) {
|
||||||
startDetails(newWalletFile, password, GenerateReviewFragment.VIEW_ACCEPT);
|
startDetails(newWalletFile, password, GenerateReviewFragment.VIEW_TYPE_ACCEPT);
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(LoginActivity.this,
|
Toast.makeText(LoginActivity.this,
|
||||||
getString(R.string.generate_wallet_create_failed), Toast.LENGTH_LONG).show();
|
getString(R.string.generate_wallet_create_failed), Toast.LENGTH_LONG).show();
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
@ -34,6 +35,7 @@ import android.widget.EditText;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.EncodeHintType;
|
import com.google.zxing.EncodeHintType;
|
||||||
|
@ -43,8 +45,8 @@ import com.google.zxing.qrcode.QRCodeWriter;
|
||||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.service.MoneroHandlerThread;
|
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -187,9 +189,7 @@ public class ReceiveFragment extends Fragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void show(final String address) {
|
private void show(String address) {
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
tvAddress.setText(address);
|
tvAddress.setText(address);
|
||||||
etPaymentId.setEnabled(true);
|
etPaymentId.setEnabled(true);
|
||||||
etAmount.setEnabled(true);
|
etAmount.setEnabled(true);
|
||||||
|
@ -198,27 +198,41 @@ public class ReceiveFragment extends Fragment {
|
||||||
hideProgress();
|
hideProgress();
|
||||||
generateQr();
|
generateQr();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
private void show(String walletPath, String password) {
|
||||||
|
new ReceiveFragment.AsyncShow().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR,
|
||||||
|
walletPath, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void show(final String walletPath, final String password) {
|
private class AsyncShow extends AsyncTask<String, Void, Boolean> {
|
||||||
new Thread(null,
|
String password;
|
||||||
new Runnable() {
|
|
||||||
|
String address;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
protected Boolean doInBackground(String... params) {
|
||||||
final Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
if (params.length != 2) return false;
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
String walletPath = params[0];
|
||||||
public void run() {
|
password = params[1];
|
||||||
String address = wallet.getAddress();
|
Wallet wallet = WalletManager.getInstance().openWallet(walletPath, password);
|
||||||
|
address = wallet.getAddress();
|
||||||
wallet.close();
|
wallet.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
super.onPostExecute(result);
|
||||||
|
if (result) {
|
||||||
show(address);
|
show(address);
|
||||||
}
|
} else {
|
||||||
});
|
Toast.makeText(getActivity(), getString(R.string.receive_cannot_open), Toast.LENGTH_LONG).show();
|
||||||
|
hideProgress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
, "Receive", MoneroHandlerThread.THREAD_STACK_SIZE).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean amountOk() {
|
private boolean amountOk() {
|
||||||
String amountEntry = etAmount.getText().toString();
|
String amountEntry = etAmount.getText().toString();
|
||||||
if (amountEntry.isEmpty()) return true;
|
if (amountEntry.isEmpty()) return true;
|
||||||
|
|
|
@ -24,7 +24,6 @@ import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.UrlQuerySanitizer;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
|
@ -35,8 +34,6 @@ import android.support.v4.app.FragmentTransaction;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
@ -49,7 +46,6 @@ import com.m2049r.xmrwallet.util.BarcodeData;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.TxData;
|
import com.m2049r.xmrwallet.util.TxData;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -594,7 +590,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case DialogInterface.BUTTON_POSITIVE:
|
case DialogInterface.BUTTON_POSITIVE:
|
||||||
Bundle extras = new Bundle();
|
Bundle extras = new Bundle();
|
||||||
extras.putString("type", GenerateReviewFragment.VIEW_WALLET);
|
extras.putString("type", GenerateReviewFragment.VIEW_TYPE_WALLET);
|
||||||
replaceFragment(new GenerateReviewFragment(), null, extras);
|
replaceFragment(new GenerateReviewFragment(), null, extras);
|
||||||
break;
|
break;
|
||||||
case DialogInterface.BUTTON_NEGATIVE:
|
case DialogInterface.BUTTON_NEGATIVE:
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 m2049r
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.util;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.service.MoneroHandlerThread;
|
||||||
|
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
|
||||||
|
public class MoneroThreadPoolExecutor {
|
||||||
|
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
|
||||||
|
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
|
||||||
|
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
|
||||||
|
private static final int KEEP_ALIVE_SECONDS = 30;
|
||||||
|
|
||||||
|
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
|
||||||
|
private final AtomicInteger mCount = new AtomicInteger(1);
|
||||||
|
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
return new Thread(null, r, "MoneroTask #" + mCount.getAndIncrement(), MoneroHandlerThread.THREAD_STACK_SIZE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final BlockingQueue<Runnable> sPoolWorkQueue =
|
||||||
|
new LinkedBlockingQueue<>(128);
|
||||||
|
|
||||||
|
public static final Executor MONERO_THREAD_POOL_EXECUTOR;
|
||||||
|
|
||||||
|
static {
|
||||||
|
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
|
||||||
|
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
|
||||||
|
sPoolWorkQueue, sThreadFactory);
|
||||||
|
threadPoolExecutor.allowCoreThreadTimeOut(true);
|
||||||
|
MONERO_THREAD_POOL_EXECUTOR = threadPoolExecutor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -177,6 +177,7 @@
|
||||||
<string name="receive_paymentid_hint">(optional)</string>
|
<string name="receive_paymentid_hint">(optional)</string>
|
||||||
<string name="receive_amount_label">Amount</string>
|
<string name="receive_amount_label">Amount</string>
|
||||||
<string name="receive_amount_hint">(optional)</string>
|
<string name="receive_amount_hint">(optional)</string>
|
||||||
|
<string name="receive_cannot_open">Could not open wallet!</string>
|
||||||
|
|
||||||
<string name="details_alert_message">Sensitive data will now be shown.\nLook over your shoulder!</string>
|
<string name="details_alert_message">Sensitive data will now be shown.\nLook over your shoulder!</string>
|
||||||
<string name="details_alert_yes">I\'m safe</string>
|
<string name="details_alert_yes">I\'m safe</string>
|
||||||
|
|
Loading…
Reference in New Issue