patternjavaMinor
Reducing repetitive Android code
Viewed 0 times
coderepetitivereducingandroid
Problem
How can I reduce the amount of repetitive code in my Android app? A lot of the code seems to be doing the same thing twice. I think that there is a more compact way to do this.
What are some ways that I can reduce lines of code in this program?
Is there a better way that I could write this program? I think that I am taking more steps than necessary.
The code is for this app.
```
package com.kerseykyle.easyhash;
import java.security.MessageDigest;
import android.os.Build;
import android.os.Bundle;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Share();
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent); // Handle text being sent
}
}
EditText myTextBox = (EditText) findViewById(R.id.input);
myTextBox.setSingleLine(true);
myTextBox.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onTextChanged(CharSequence s, int start, int before,
int count) {
String md5hash = CreateHash(s.toString(), "MD5");
TextView md5 = (TextView) findV
What are some ways that I can reduce lines of code in this program?
Is there a better way that I could write this program? I think that I am taking more steps than necessary.
The code is for this app.
```
package com.kerseykyle.easyhash;
import java.security.MessageDigest;
import android.os.Build;
import android.os.Bundle;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Share();
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
handleSendText(intent); // Handle text being sent
}
}
EditText myTextBox = (EditText) findViewById(R.id.input);
myTextBox.setSingleLine(true);
myTextBox.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onTextChanged(CharSequence s, int start, int before,
int count) {
String md5hash = CreateHash(s.toString(), "MD5");
TextView md5 = (TextView) findV
Solution
This type of problem is conveniently solved with a Strategy Pattern. But, first things first:
As for the Strategy Pattern.... In this case, you can create a class that listens for the text change, and updates the signature in the linked TextView. The same class listens for on-click on the TextView too. The class could have the signature
You can see the pattern that is emerging above. Obviously there are issues in the onClick method, but this is from copy/pasting your code.
Now, what you do in your
After that, the system should be self-managing.
You only have one copy of the code, and the only things different about it are the name of the Digest and the target of the TextView.
- you should search for efficient ways to convert bytes to hexadecimal-string values. This is a great solution I like....
- Unless you have no choice (you are using Patterns/Matchers) you should always use StringBuilder instead of StringBuffer
- The method
CreateHashshould not have a capital-letter to start with, it should rather becreateHash
As for the Strategy Pattern.... In this case, you can create a class that listens for the text change, and updates the signature in the linked TextView. The same class listens for on-click on the TextView too. The class could have the signature
public abstract class HashDigestDisplay implements TextWatcher, OnClickListener {
private final TextView view;
private final MessageDigest digest;
public HashDigestDisplay (TextView target, String digestName) throws NoSuchAlgorithmException {
this.view = target;
this.digest = MessageDigest.getInstance(digestName);
this.view.setOnClickListener(this);
}
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
private String myDigest(String input) {
digest.reset();
byte[] hash = digest.digest(input.getBytes("UTF-8"));
return bytesToHex(hash);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onTextChanged(CharSequence s, int start, int before, int count) {
view.setText(myDigest(s.toString()));
view.setTextIsSelectable(true);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
EditText myTextBox = (EditText) findViewById(R.id.input);
String hash = myDigest(myTextBox.getText().toString());
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, hash);
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
}You can see the pattern that is emerging above. Obviously there are issues in the onClick method, but this is from copy/pasting your code.
Now, what you do in your
onCreate() setup method is simply:myTextBox.addTextChangedListener(
new HashDigestDisplay((TextView) findViewById(R.id.md5), "MD5"));
myTextBox.addTextChangedListener(
new HashDigestDisplay((TextView) findViewById(R.id.sha1), "SHA-1"));
....After that, the system should be self-managing.
You only have one copy of the code, and the only things different about it are the name of the Digest and the target of the TextView.
Code Snippets
public abstract class HashDigestDisplay implements TextWatcher, OnClickListener {
private final TextView view;
private final MessageDigest digest;
public HashDigestDisplay (TextView target, String digestName) throws NoSuchAlgorithmException {
this.view = target;
this.digest = MessageDigest.getInstance(digestName);
this.view.setOnClickListener(this);
}
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
private String myDigest(String input) {
digest.reset();
byte[] hash = digest.digest(input.getBytes("UTF-8"));
return bytesToHex(hash);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onTextChanged(CharSequence s, int start, int before, int count) {
view.setText(myDigest(s.toString()));
view.setTextIsSelectable(true);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
EditText myTextBox = (EditText) findViewById(R.id.input);
String hash = myDigest(myTextBox.getText().toString());
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, hash);
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
}myTextBox.addTextChangedListener(
new HashDigestDisplay((TextView) findViewById(R.id.md5), "MD5"));
myTextBox.addTextChangedListener(
new HashDigestDisplay((TextView) findViewById(R.id.sha1), "SHA-1"));
....Context
StackExchange Code Review Q#38132, answer score: 4
Revisions (0)
No revisions yet.