Make final copies of non-volatile fields when passing to other threads.

This commit is contained in:
akwizgran
2013-03-11 15:58:22 +00:00
parent 7f71c1d5e7
commit 035fb2ca9a
6 changed files with 79 additions and 79 deletions

View File

@@ -88,6 +88,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
// Add some fake contacts to the database in a background thread // Add some fake contacts to the database in a background thread
// FIXME: Remove this // FIXME: Remove this
final DatabaseComponent db = this.db;
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
public void run() { public void run() {
try { try {
@@ -137,6 +138,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
} }
private void reloadContactList() { private void reloadContactList() {
final DatabaseComponent db = this.db;
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
public void run() { public void run() {
try { try {

View File

@@ -217,6 +217,7 @@ implements InvitationListener {
} }
void addContactAndFinish(final String nickname) { void addContactAndFinish(final String nickname) {
final DatabaseComponent db = this.db;
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
public void run() { public void run() {
try { try {

View File

@@ -121,6 +121,7 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
} }
private void reloadMessageHeaders() { private void reloadMessageHeaders() {
final DatabaseComponent db = this.db;
final ContactId contactId = this.contactId; final ContactId contactId = this.contactId;
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
public void run() { public void run() {

View File

@@ -93,6 +93,8 @@ implements OnClickListener, DatabaseListener {
// Add some fake messages to the database in a background thread // Add some fake messages to the database in a background thread
// FIXME: Remove this // FIXME: Remove this
final DatabaseComponent db = this.db;
final MessageFactory messageFactory = this.messageFactory;
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
public void run() { public void run() {
try { try {
@@ -183,6 +185,7 @@ implements OnClickListener, DatabaseListener {
} }
private void reloadMessageHeaders() { private void reloadMessageHeaders() {
final DatabaseComponent db = this.db;
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
public void run() { public void run() {
try { try {

View File

@@ -89,27 +89,7 @@ implements OnClickListener {
} else { } else {
starred = i.getBooleanExtra("net.sf.briar.STARRED", false); starred = i.getBooleanExtra("net.sf.briar.STARRED", false);
read = false; read = false;
final MessageId id = messageId; setReadInDatabase(true);
dbExecutor.execute(new Runnable() {
public void run() {
try {
serviceConnection.waitForStartup();
db.setReadFlag(id, true);
runOnUiThread(new Runnable() {
public void run() {
setRead(true);
}
});
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} catch(InterruptedException e) {
if(LOG.isLoggable(INFO))
LOG.info("Interrupted while waiting for service");
Thread.currentThread().interrupt();
}
}
});
} }
LinearLayout layout = new LinearLayout(this); LinearLayout layout = new LinearLayout(this);
@@ -204,9 +184,40 @@ implements OnClickListener {
serviceConnection, 0); serviceConnection, 0);
} }
private void loadMessageBody() { private void setReadInDatabase(final boolean read) {
final DatabaseComponent db = this.db;
final MessageId messageId = this.messageId;
dbExecutor.execute(new Runnable() {
public void run() {
try {
serviceConnection.waitForStartup();
db.setReadFlag(messageId, read);
setReadInUi(read);
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} catch(InterruptedException e) {
if(LOG.isLoggable(INFO))
LOG.info("Interrupted while waiting for service");
Thread.currentThread().interrupt();
}
}
});
}
private void setReadInUi(final boolean read) {
runOnUiThread(new Runnable() {
public void run() {
ReadMessageActivity.this.read = read;
if(read) readButton.setImageResource(R.drawable.content_unread);
else readButton.setImageResource(R.drawable.content_read);
}
});
}
private void loadMessageBody() {
final DatabaseComponent db = this.db;
final MessageId messageId = this.messageId; final MessageId messageId = this.messageId;
final TextView content = this.content;
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
public void run() { public void run() {
try { try {
@@ -247,28 +258,7 @@ implements OnClickListener {
public void onClick(View view) { public void onClick(View view) {
if(view == readButton) { if(view == readButton) {
final MessageId messageId = this.messageId; setReadInDatabase(!read);
final boolean read = !this.read;
dbExecutor.execute(new Runnable() {
public void run() {
try {
serviceConnection.waitForStartup();
db.setReadFlag(messageId, read);
runOnUiThread(new Runnable() {
public void run() {
setRead(read);
}
});
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} catch(InterruptedException e) {
if(LOG.isLoggable(INFO))
LOG.info("Interrupted while waiting for service");
Thread.currentThread().interrupt();
}
}
});
} else if(view == prevButton) { } else if(view == prevButton) {
setResult(RESULT_PREV); setResult(RESULT_PREV);
finish(); finish();
@@ -284,10 +274,4 @@ implements OnClickListener {
finish(); finish();
} }
} }
private void setRead(boolean read) {
this.read = read;
if(read) readButton.setImageResource(R.drawable.content_unread);
else readButton.setImageResource(R.drawable.content_read);
}
} }

View File

@@ -59,6 +59,7 @@ implements OnClickListener, OnItemSelectedListener {
private ContactId contactId = null; private ContactId contactId = null;
private MessageId parentId = null; private MessageId parentId = null;
private ContactNameSpinnerAdapter adapter = null; private ContactNameSpinnerAdapter adapter = null;
private Spinner spinner = null;
private ImageButton sendButton = null; private ImageButton sendButton = null;
private EditText content = null; private EditText content = null;
@@ -88,32 +89,10 @@ implements OnClickListener, OnItemSelectedListener {
actionBar.addView(to); actionBar.addView(to);
adapter = new ContactNameSpinnerAdapter(this); adapter = new ContactNameSpinnerAdapter(this);
final Spinner spinner = new Spinner(this); spinner = new Spinner(this);
spinner.setAdapter(adapter); spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this); spinner.setOnItemSelectedListener(this);
dbExecutor.execute(new Runnable() { loadContactNames();
public void run() {
try {
serviceConnection.waitForStartup();
final Collection<Contact> contacts = db.getContacts();
runOnUiThread(new Runnable() {
public void run() {
for(Contact c : contacts) {
if(c.getId().equals(contactId))
spinner.setSelection(adapter.getCount());
adapter.add(c);
}
}
});
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} catch(InterruptedException e) {
LOG.info("Interrupted while waiting for service");
Thread.currentThread().interrupt();
}
}
});
actionBar.addView(spinner); actionBar.addView(spinner);
actionBar.addView(new HorizontalSpace(this)); actionBar.addView(new HorizontalSpace(this));
@@ -141,6 +120,33 @@ implements OnClickListener, OnItemSelectedListener {
serviceConnection, 0); serviceConnection, 0);
} }
private void loadContactNames() {
final DatabaseComponent db = this.db;
dbExecutor.execute(new Runnable() {
public void run() {
try {
serviceConnection.waitForStartup();
final Collection<Contact> contacts = db.getContacts();
runOnUiThread(new Runnable() {
public void run() {
for(Contact c : contacts) {
if(c.getId().equals(contactId))
spinner.setSelection(adapter.getCount());
adapter.add(c);
}
}
});
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
} catch(InterruptedException e) {
LOG.info("Interrupted while waiting for service");
Thread.currentThread().interrupt();
}
}
});
}
@Override @Override
public void onSaveInstanceState(Bundle state) { public void onSaveInstanceState(Bundle state) {
Parcelable p = content.onSaveInstanceState(); Parcelable p = content.onSaveInstanceState();
@@ -156,16 +162,20 @@ implements OnClickListener, OnItemSelectedListener {
public void onClick(View view) { public void onClick(View view) {
if(contactId == null) throw new IllegalStateException(); if(contactId == null) throw new IllegalStateException();
final Message m;
try { try {
byte[] body = content.getText().toString().getBytes("UTF-8"); byte[] body = content.getText().toString().getBytes("UTF-8");
m = messageFactory.createPrivateMessage(parentId, "text/plain", storeMessage(messageFactory.createPrivateMessage(parentId,
body); "text/plain", body));
} catch(IOException e) { } catch(IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} catch(GeneralSecurityException e) { } catch(GeneralSecurityException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
finish();
}
private void storeMessage(final Message m) {
final DatabaseComponent db = this.db;
final ContactId contactId = this.contactId; final ContactId contactId = this.contactId;
dbExecutor.execute(new Runnable() { dbExecutor.execute(new Runnable() {
public void run() { public void run() {
@@ -182,7 +192,6 @@ implements OnClickListener, OnItemSelectedListener {
} }
} }
}); });
finish();
} }
public void onItemSelected(AdapterView<?> parent, View view, int position, public void onItemSelected(AdapterView<?> parent, View view, int position,