Good method practice in Java - java

In my Android application I have a new intent which is launched depending on the results and returns of some other methods, so I've launched the intent this way:
methodOne(methodTwo(methodThree()));
This is the code for launch search results:
private void methodOne(ArrayList<String> identities) {
Intent intent = new Intent(Class.this, AnotherClass.class);
intent.putStringArrayListExtra("aList", identities);
startActivity(intent);
}
This currently works fine, and I get the results I want. I just wondered if the way I am calling this method is good or bad practice as I don't really know myself.

If you are passing the ArrayList of event identities to the function when you call it, there is no need to do the:
eventIdentities = getEventIdentities(searchResults);
because you already have the ArrayList being passed into the method so you can use it.

Related

Which is considered better to pass information between Activities on Android project, send a model or only an id?

I have an android app and I have 3 screens that the user must fill some fields. Each screen have 7 fields to be filled. At the end of the process, I submit the information to the server using Retrofit with an API.
This is how I pass the information between Activities in my first project
// first activity
AutoDados autuacaoDados = new AutoDados(... a lot of parameters ...);
Intent intent1 = new Intent(AutoInf_Lista_Generica.this, AutoInf_Menu.class);
intent1.putExtra("PARAM_ENV_DADOS", autuacaoDados);
startActivity(intent1);
// second activity
Bundle extras = intent.getExtras();
if (extras == null) {
return "";
}
AutoDados autuacaoDados = (AutoDados) extras.getSerializable("PARAM_ENV_DADOS");
I have another project that I use the following code to pass data between activities.
// first activity
Intent intent1 = new Intent(AutoInf_Lista_Generica.this, AutoInf_Menu.class);
intent1.putExtra("ID_AUTOS", myId);
startActivity(intent1);
// second activity
intent.getIntExtra("ID_AUTOS", 0);
// code that recover the data from a SQLite database based in the "ID_AUTOS"
These both ways I was able to recover data between activities, but which way is considered better and why is it better?
Another question, is there a better way to pass data between activities ?
If possible, talk about the pros and cons about each approach.
The main difference between the tow ways is that in the first method you are passing an Object to the second activity while in the second method you are passing a primitive type.
which is better ? each way has its own use case, there is no better way, it depends on your use case

Passing class in universal intent

So, right now in my App I'm sending data from actual class, to other, special class prepared to show informations from it, like here:
Intent intent = new Intent(ActualFluidsBernoullisEquationMenuActivity.this, DetailSubjectActivity.class);
Of course I'm also passing some info, on which I first need to create database reference, so there is like 15 lines of code.I have like 15 of those activities, which is creating a lot of boilerplate (the only changing line is which .this class I'm passing)
So I wanted to create universal method for intent like this:
Intent engineeringTheoryIntent(String callingActivity, String subjectKey) throws ClassNotFoundException {
Intent intent = new Intent(Class.forName(callingActivity).getClass().this, DetailSubjectActivity.class);
}
(This doesn't work, just in case)
I just cannoot find the way how to properly pass first class. I tried Class.forName, I tried passing whole class, but not any of those works for me. I also didn't find any info if this is even possible (I'm kind of beginner in matter of android). So is there way to do it?
I'm posting the solution in the comments as an answer, so that it helps people who encounter similar problems in future.
So, instead of passing the activity class name (as String) you can simply pass the Activity itself as the argument to your universal function, like this :
Intent engineeringTheoryIntent(Activity callingActivity, String subjectKey) throws ClassNotFoundException {
and then you can create your Intent using it like this :
Intent intent = new Intent(callingActivity, DetailSubjectActivity.class);
So, your function will look something like this:
Intent engineeringTheoryIntent(Activity callingActivity, String subjectKey) throws ClassNotFoundException {
Intent intent = new Intent(callingActivity, DetailSubjectActivity.class);
}

ClassCastException on custom object with child objects which is parcelable

Good day,
I was assigned to an android project inside my company and I'm having a little bit of a struggle. I have not touched Android in a few years. Figured you might be able to help me find what i am missing.
I have a project that calls an external libratry for reading a barcode, then the code does a parsing of the byte array and converts it into an object. The problem I am having is of comunication between my MainActivity and the activity that scans the barcode.
This is the piece of code that calls my barcode reader activity:
setContentView(R.layout.activity_main);
MyObjectActivity.setParentActivity(this);
Intent intent = new Intent(this, MyObjectActivity.class);
startActivityForResult(intent, 0);
This one should escalate the scanned data from MyObjectActivity object into my MainActivity (so i can actually do something with the data).
try
{
//MyObject objet contains child objects
MyObject content = MyObjectParser.retrieveContentData(data /*contains the byte array*/);
Intent data_toreturn = new Intent();
data_toreturn.putExtra("data_sent", true);
data_toreturn.putExtra(BARCODE_DATA_EXTRA_TAG, content);
if (getParent() == null)
{
setResult(RESULT_OK, data_toreturn);
} else
getParent().setResult(RESULT_OK, data_toreturn);
} catch(final RuntimeException e)
{
parentActivity.runOnUiThread(new Runnable()
{
#Override
public void run()
{
Toast.makeText(parentActivity, e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
// stop the Activity
finish();
While debugging i manage to run all the code up until the finish(). Then i get the exception
Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { (has extras) }} to activity {MyObjectActivity}: java.lang.ClassCastException: java.lang.Object[] cannot be cast to ChildObject[]
According to what I remember from developping in android, in order to be able to pass Objects between Activities you need intents and Objects that are Parcelable or Serializable (not sure about this one). I've reviewed the code and the sub objects DO implement this.
I really don't know how to continue. It is either a thing of configuration, or I am doing something very wrong and I am not seeing it.
Thank you for your response.
So I see you are using
startActivityForResult(intent, Yournumber) //I would not use 0, use 1001 or something more custom.
so that you make yourself the parent of the launched activity.
So why are you doing the setParentActivity call? I assume just for doing your Toast? Seems like a unhealthy way to handle that, but that is a different issue.
Then override onActivityResult in that parent activity to handle the intent data returned. As I'm sure you have already done.
But I'm not certain of your "content" object if it is parcable or not. You can check by simply commenting out "adding that to the intent" and seeing if it gets delivered when that object is not inside the intent.
If it is delivered then you should ensure that your object implements Parceable so that it can be put in the intents. If it still does not get delivered then it would appear you are having an issue with your parent not pointing to the correct class somehow and we would need to see more code to help out on that.
I see you are passing the raw bytes, which should work fine, but you could try a wrapper object that implements parceable as well that holds the bytes as a member and pass back that object as a last ditch effort as well.
Let's assume you're sending an Object X via an explicit Intent from Activity A to Activity B.
Step 1 - make sure your class X implements Serializable interface (which you said you already have). Also make sure that all other objects inside your Object X do implement Serializable interface.
Step 2 - Somewhere inside your Activity A you'd have similar code:
X objectX = new X();
Intent intent = new Intent(A.this, B.class);
intent.putExtra("myObject", objectX);
startActivity(intent);
Step 3 - Inside your Activity B you will get the Object reference and typecast it to X:
Intent intent = getIntent();
X objectX = (X)intent.getSerializableExtra("myObject");
Hope this helps. This is the basic pattern of passing objects between Activities and there is nothing more to it.

Intent putExtra(String,String) inside of AsyncTask

I'm simply trying to carry a string onto the next activity without having to define an entire object for the task. I've seen similar solutions and gotten them to work BUT without using AsyncTask to create the intent.
protected void onPostExecute(Boolean result) {
if (loggedIn && hasPin) {
Intent intent = new Intent(UniteActivity.this,
WebViewActivity.class);
intent.putExtra(PASSED_USERNAME, passUser);
startActivity(intent);
}
if (loggedIn && !hasPin) {
Intent intent = new Intent(UniteActivity.this,
CreatePinActivity.class);
intent.putExtra(PASSED_USERNAME, passUser);
startActivity(intent);
PASSED_USERNAME is a public static constant to hold the package name, just as the putExtra() method requires. I then try to pull the value out in the next activity.
Intent extras = getIntent();
String username = extras.getStringExtra(UniteActivity.PASSED_USERNAME);
// carry username to next activity
Intent intent = new Intent(CreatePinActivity.this,WebViewActivity.class);
intent.putExtra(PASSED_USERNAME, username);
startActivity(intent);
There is never a String to pull out, the value of username is always null. I've gone through the debugger and found that the Eclipse IDE debugger shows different intent ID's between the activities, they are never consistant. Is it possible that AsyncTask is interfereing somehow because it splits into a seperate thread?
I don't know if this applies to your problem, because I can't see from your code snippet if the intermediary activity is freshly created or not.
BUT: the getIntent()-method always returns the first Intent that started the activity. If the activity remains in the background and receives a new Intent this value does not get updated automatically. You have to override onNewIntent(...) and manually call setIntent(...) for this to work (or do all your stuff directly there).
So just for the case that you do not run your posted code in the onCreate() method please check if you did not miss to fetch the real intent you are interested in.
Not sure of the exact answer for you solution.
You calling startActivity on the UI since it's in postExecute().
If all else fails you can just save that value to a sharedpreference.
The way you have handled the variable PASSED_USERNAME seems incorrect. You have used it in some palaces as simple PASSED_USERNAME whereas in some other places you have used it with the class named prefixed UniteActivity.PASSED_USERNAME. Since it is a Public Static Constant always use it prefixed with the class name.

Puzzling java.lang.NullPointerException in Android App

I'm currently working on an Android App and, almost every time I use it, I get a an error. Most of the time it doesn't crash the app, but it is still frustrating that I'm seeing this error. I thought I did a check for it, but I could be wrong. Thanks for the help! The relevant code is below. (It's relevant because the line outside the if statement is throwing the NullPointerException.)
Activity activity;
if(activity == null)
{
activity = new Activity();
}
Intent intent = new Intent(activity, Service.class);
You don't usually instantiate the Activity class in this manner. Please see the documentation on the Android Activity class here:
http://developer.android.com/reference/android/app/Activity.html
You should post some more of the surrounding code, but your problem is that creating new Intent requires a valid Context. Usually you create an Intent within an Activity (or Service or BroadcastReceiver) class so you can just do something like:
Intent intent = new Intent(this, Service.class);
Occasionally you'll create it somewhere else and pass it that valid Context, but you should pretty much never create an Activity by calling the constructor directly. There's a lot of other initialization necessary to make it useful.
As postet previously there is more to initiate for an activity than calling the constructor. Probably you get a null pointer exception deep within the Intent Constructer where it is trying to get some of the Activityinformation usually provided.
If you really want to create a Service, heres a link for starting a Service, but you should really read the whole article and probably some more of the activity lifecycle ressources.
http://developer.android.com/guide/topics/fundamentals/services.html#StartingAService

Categories

Resources