たくさんのコードを投稿してしまったことを前もってお詫びします。この問題は本当に私を襲いました!
問題を引き起こしているAndroidJUnitテストが2つあります。それぞれを個別に実行すると正常に機能しますが、一度に実行すると(PasswordEntryActivityTests、次にCryptoKeystoreTests)、CryptoKeystoreTestsが無期限にハングします。
それぞれが1秒未満で個別に終了するため、エミュレータが遅いだけでなく、20分以上ハングする可能性があることを私は知っています。また、実際のデバイス(Droid Razr)でテストしましたが、同じことを行います。
問題のあるコードはPasswordEntryActivity.launchNewPasswordActivity()
です。その機能を削除すると、すべてが正常に機能します。
ハングしているときにデバッガーで関数を一時停止すると、次のようになります。
MessageQueue.nativePollOnce(int, int) line: not available [native method]
どうしたの?
以下にコピーしました:
- PasswordEntryActivity
- PasswordEntryActivityTests
- CryptoManagerKeystoreTests
あなたが見たい他のコードを投稿することを私に知らせてください。ありがとう!
public class PasswordEntryActivity extends Activity
{
...
private void launchNewPasswordActivity()
{
Intent launchNewPasswordIntent = new Intent(this, NewPasswordActivity.class);
startActivity(launchNewPasswordIntent);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.password_entry_layout);
...
//this code should be LAST in onCreate because it exits the Activity
//CryptoManager.passwordIsRight returns 0 if no password has been set
passwordExists = CryptoManager.passwordIsRight("x", this) != 0;
if(!passwordExists)
launchNewPasswordActivity();
}
}
そのアクティビティのテスト:
//supposed to make sure the application responds correctly when no password is set
public class PasswordEntryActivityTests extends android.test.ActivityInstrumentationTestCase2< crypnote.controller.main.PasswordEntryActivity>{
protected void setUp() throws Exception
{
passwordEntryActivity = getActivity();
//delete the database if it exists
File file = passwordEntryActivity.getFileStreamPath(DBInterface.Constants.DatabaseName);
if(file.exists())
assertTrue(file.delete());
file = passwordEntryActivity.getFileStreamPath(CryptoManager.Constants.KEYSTORE_PATH);
if(file.exists())
assertTrue(file.delete());
}
//allows us to access the interface
@UiThreadTest
public void testNoPassword() throws Exception
{
passwordEntryActivity = getActivity();
EditText passwordEntryEditText =
(EditText) passwordEntryActivity.findViewById(
crypnote.controller.main.R.id.passwordentrylayout_passwordedittext);
Button unlockButton = (Button) passwordEntryActivity.findViewById(
crypnote.controller.main.R.id.passwordentrylayout_unlockbutton);
int passwordResult = CryptoManager.passwordIsRight("x", getActivity());
assertTrue(passwordResult == 0);
//pass a wrong password to the edittext and click the unlock button
passwordEntryEditText.setText("x");
assertTrue(unlockButton.performClick());
//get the foreground activity class name
ActivityManager am = (ActivityManager) passwordEntryActivity.
getSystemService(Context.ACTIVITY_SERVICE);
// get the info from the currently running task
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
String foregroundClassName = componentInfo.getShortClassName();
//don't forget the leading '.'
assertTrue(!foregroundClassName.equals(".PasswordEntryActivity"));
}
}
CryptoKeystoreTests:
public class CryptoKeystoreTests extends android.test.ActivityInstrumentationTestCase2<
crypnote.controller.main.PasswordEntryActivity>
{
public void testKeystore() throws Exception
{
Context context = getActivity();
//delete the database if it exists
File file = context.getFileStreamPath(DBInterface.Constants.DatabaseName);
if(file.exists())
assertTrue(file.delete());
file = context.getFileStreamPath(CryptoManager.Constants.KEYSTORE_PATH);
if(file.exists())
assertTrue(file.delete());
CryptoManager cryptoManager=null;
String password = CryptoManager.Constants.DEBUG_PASSWORD;
FileInputStream fis=null;
//the cryptomanager will generate a new key and keystore
cryptoManager = new CryptoManager(password, context);
Key CRYPTOKEY = cryptoManager.getKey();
cryptoManager.close();
//initialize KeyStore
KeyStore keystore = KeyStore.getInstance(Constants.KEYSTORE_INSTANCE_TYPE);
fis = context.openFileInput(CryptoManager.Constants.KEYSTORE_PATH);
keystore.load(fis, password.toCharArray());
assertTrue(keystore.containsAlias(Constants.APP_ALIAS));
assertTrue(keystore.isKeyEntry(Constants.APP_ALIAS));
Key key = keystore.getKey(CryptoManager.Constants.APP_ALIAS,
password.toCharArray());
assertTrue(key.getAlgorithm().equals(CryptoManager.Constants.PROVIDER_NAME));
assertTrue(key.getAlgorithm().equals(CRYPTOKEY.getAlgorithm()));
assertTrue(key.getFormat().equals(CRYPTOKEY.getFormat()));
if(fis != null)
fis.close();
}
}
編集:NewPasswordActivity.onCreate:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.new_password_layout);
}