This is a complete login activity class.
What I need reviewed:
- I need simplify my code as much as possible.
- Is it wise to use the butterknife library, or is the normal way better?
- Hide keyboard when user touches out away from edit text, and when selecting "login."
- Best practise for volley library. Should I use it individual in each class (login, sign up) or I should make a general function in an API class?
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.imaadv.leaynik.api.API;
import com.imaadv.leaynik.api.ConnectionExector.HTTPResponse;
import com.imaadv.leaynik.api.ConnectionExector.ResponseType;
import com.imaadv.leaynik.api.ConnectionExector.onHttpRequestListener;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.imaadv.leaynik.api.JsonParsing;
import com.imaadv.leaynik.api.MySingleton;
import com.imaadv.leaynik.defs.AppConstants;
import com.imaadv.leaynik.defs.userdata;
import com.imaadv.leaynik.R;
import java.util.HashMap;
import java.util.Map;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnCheckedChanged;
import butterknife.OnClick;
public class LoginActivity extends AppCompatActivity {
private static final String TAG = LoginActivity.class.getSimpleName();
@Bind(R.id.input_username)
EditText _UsernameText;
@Bind(R.id.input_password)
EditText _PasswordText;
@Bind(R.id.btn_login)
Button _LoginButton;
@Bind(R.id.tv_singup)
TextView _SignUpButton;
@Bind(R.id.checkbox_remember)
CheckBox _chkRemember;
@Bind(R.id.tv_forgetpassword)
TextView forgetpassword;
private static final int FIRST_ITEM_INDEX = 0;
private API api;
private ProgressDialog progressD;
private LinearLayout loginLinear;
private boolean remember_me = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.signin);
ButterKnife.bind(this);
api = new API(this);
loginLinear = (LinearLayout) findViewById(R.id.loginView);
HideKeyboardFromView(loginLinear);
init();
}
public static void hideSoftKeyboard(Activity act) {
InputMethodManager mInputMange = (InputMethodManager) act
.getSystemService(Context.INPUT_METHOD_SERVICE);
mInputMange.hideSoftInputFromWindow(act.getCurrentFocus()
.getWindowToken(), 0);
}
public void HideKeyboardFromView(View view) {
if (!(view instanceof EditText)) {
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
hideSoftKeyboard(LoginActivity.this);
return false;
}
});
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
HideKeyboardFromView(innerView);
}
}
}
@OnClick(R.id.btn_login)
public void submitLogin(View view) {
SingInMethod();
}
@OnClick(R.id.tv_singup)
public void submitSingUp(View view) {
SingUpMethod();
}
@OnClick(R.id.tv_forgetpassword)
public void submitForgetPassword(View view){
Forget_Password_method();
}
@OnCheckedChanged(R.id.checkbox_remember)
public void checkbox(CheckBox cb , boolean checked){
remember_me = checked ;
}
private void init() {
String rem = api.getSetting(AppConstants.REMEMBER_ME);
if (rem != null && rem.equals(AppConstants.TRUE) ) {
_UsernameText.setText(api.getSetting(AppConstants.TAG_username));
}
progressD = new ProgressDialog(this);
progressD.setCancelable(false);
progressD.setMessage(getResources().getString(R.string.loading));
progressD.setProgressStyle(ProgressDialog.STYLE_SPINNER);
}
private void get_user_data(userdata user) {
final JsonParsing jsonParser = new JsonParsing();
Map<String, String> params = new HashMap<>();
params.put(AppConstants.TAG_username, user.username);
params.put(AppConstants.TAG_userpassword, user.password);
String URL = AppConstants.GeneralURL + AppConstants.ACTION + AppConstants.LOGIN;
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
progressD.hide();
try {
String res = response.getString(AppConstants.RESULT);
if (res.equals(AppConstants.FALSE)) {
String error = (String) response.get(AppConstants.MESSAGE);
Toast.makeText(LoginActivity.this, error, Toast.LENGTH_LONG).show();
} else if (res.equals(AppConstants.TRUE)) {
userdata user = jsonParser.getUserDataObject((JSONObject) response.get(AppConstants.MESSAGE));
api.setSetting(AppConstants.USER_ID, user.userid);
api.setSetting(AppConstants.TAG_username, user.username);
api.setSetting(AppConstants.TAG_age, user.age);
api.setSetting(AppConstants.TAG_useremail, user.email);
api.setSetting(AppConstants.TAG_user_photo,
user.userimageURL);
if(remember_me){
api.setSetting(AppConstants.REMEMBER_ME , AppConstants.TRUE);
api.setSetting(AppConstants.IS_LOGGEDIN, AppConstants.TRUE);
}
Intent intent = new Intent(LoginActivity.this, Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
progressD.hide();
// handle error
}
});
MySingleton.getInstance(this.getApplicationContext()).getResquestQueue().add(jsonObjectRequest);
}
private void SingUpMethod() {
startActivity(new Intent(LoginActivity.this, Signup.class));
}
private void SingInMethod() {
if (!validate()) {
return;
}
String sPassword = _PasswordText.getText().toString();
String sUserName = _UsernameText.getText().toString();
progressD.show();
userdata user = new userdata();
user.password = sPassword;
user.username = sUserName;
if (api.isNetworkConnected()) {
get_user_data(user);
} else {
Toast.makeText(LoginActivity.this,
getResources().getString(R.string.nointernet),
Toast.LENGTH_LONG).show();
}
}
private void Forget_Password_method(){
startActivity(new Intent(LoginActivity.this, ForgetPassword.class));
}
private boolean validate() {
boolean valid = true;
String sPassword = _PasswordText.getText().toString();
String sUserName = _UsernameText.getText().toString();
if (sPassword.isEmpty() ){
_PasswordText.setError("Please enter Password");
valid = false;
}
if(sUserName.isEmpty() ){
_UsernameText.setError("Please Enter Valid E-mail");
valid = false;
}
return valid;
}
}
-
\$\begingroup\$ 1. Is the part of the json request async? can you show it? 2. What is MySingleton class? \$\endgroup\$Andrei T– Andrei T2015年10月05日 20:51:38 +00:00Commented Oct 5, 2015 at 20:51
2 Answers 2
2
As you can see here and here, the Butterknife library is advised to be used due to its simplicity that gets the job done with fewer lines of code.
1
Hints:
I would advise you to split your code into well-encapsulated parts.
For example, I would put all my JSON request code in one class and pass a callback, in case you need to return something to the activity if you got a result from the network request. The starting of an activity after you got some results is a bit inefficient.
Make smaller methods; they should not have more than 30-40 lines of code. Also, split the methods into independent logic. Do not create methods that have 100 lines of code and 3 kinds of logic inside.
For example, if you want to filter a list and save the data to a cache, you have a method for filtering the list and another for saving the filtered list to the cache.
Do not leave white spaces inside methods and between methods use max 1 line of space. Use some type of formatting.
Your code
I would create a callback that I can implement in my LoginActivity
and pass this callback to the AsynTask
/Thread
that requests the data from the server.
Once the server returns something I would return that via the callback you just passed to the asynctask (it can be a class that extends Thread
, AsyncTask
class or any other thread mechanism you may want to use).
The onResponse
method should be split into 3 different methods:
savingData
orgettingData
/parsingData
.- It should be
createIntent
orstartIntent
, etc. - In case the response is false,
showToast
, etc.
it would be a better approach if you parse the data received in form of object via different method and you may also put these methods in a seperate class so they can be used for other activities needing the same adapter class
//This method will get data from the web api
private void getData(){
//Showing a progress dialog
final ProgressDialog loading = ProgressDialog.show(this,"Loading Data", "Please wait...",false,false);
Log.i("i m in","getdata()");
//Creating a json array request
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,Config.DATA_URL,null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.i("i m in","respinse()");
loading.dismiss();
Log.d(String.valueOf(response),"response");
parseData(response);
Log.d(String.valueOf(response),"check it");
//calling method to parse json array
}},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(String.valueOf(error),"error");
}
});
//Creating request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(jsonObjectRequest);
}
private void parseData(JSONObject object){
try {
JSONObject data=object.getJSONObject("response");
Log.d(String.valueOf(data),"data in response");
JSONArray array= data.getJSONArray("docs");
Log.d(String.valueOf(array.length()),"JSON ARRAY");
for(int i = 0; i<array.length(); i++)
{
JSONObject json = null;
json = array.getJSONObject(Integer.parseInt(String.valueOf(i)));
JavaBean superHero=new JavaBean();
//getter and setter method class
superHero.setTitle(json.getString(TAG_TITLE));
// add it to array list finally
listSuperHeroes.add(superHero);
}
} catch (JSONException e) {e.printStackTrace();}
//Finally initializing our adapter
adapter = new CardAdapter(this,listSuperHeroes);
//Adding adapter to recyclerview
recyclerView.setAdapter(adapter);
}