I have a class with a lot of code. I want to put some of the methods into another class, but load them from the class that i already have. I don't want to change the contentview either. I tried
Class1:
public class Class1 extends Activity {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState;
Intent intent = new Intent (this, Class2.class);
startActivity(intent);
}
}
Class2:
public class Class2 extends Class1 {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
method2();
}
}
public void method2 {
Log.e("Error", "Wut?")
}
When i run that code, the app just displays the error message over and over. The app is probably running the "method2" method over and over again... I just want to run the "method2"once. I don't want the code in the same file either, because there is gonna be a lot of code...
All you have to do is call the class2 in a object Class. Remember that is a java class so. Call it!
Class2 newClass = new Class2();
newClass. method2();
The class2 is not a activity, is only a class for has all your methods.. It is would not extends of nothing!
As I see no sense in your approach here's a workaround.
public class Class1 extends Activity {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState;
if(!this instanceof Class2)
{
Intent intent = new Intent (this, Class2.class);
startActivity(intent);
}
}
}
Related
I want to define callback for a Notebook program that way after note saved in EditActivity,in Main Activity Update list of notes,But This does not happen.
EditActivity:
public interface OnClickDoneListener{
void onClickDone();
}
public void setOnClickDoneListener(OnClickDoneListener onClickDoneListener){
this.onClickDoneListener=onClickDoneListener;
}
btnDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (extras != null) {
myDatabase.updateRow(id, txtTitle.getText().toString(), txtDesc.getText().toString());
NoteModel noteModel = new NoteModel();
noteModel.setTitle(txtTitle.getText().toString());
noteModel.setDesc(txtDesc.getText().toString());
Intent intent = new Intent(EditActivity.this, MainActivity.class);
startActivity(intent);
onClickDoneListener.onClickDone();
} else {
Done();
}
}
});
Main Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setupViews();
getDataFromDB();
recyclerView.setAdapter(new NoteAdapter(MainActivity.this,dataList));
noteAdapter = new NoteAdapter(MainActivity.this,dataList);
recyclerView.setAdapter(noteAdapter);
fabAdd = (FloatingActionButton)findViewById(R.id.fab_main_add) ;
EditActivity editActivity = new EditActivity();
editActivity.setOnClickDoneListener(new EditActivity.OnClickDoneListener() {
#Override
public void onClickDone() {
noteAdapter.notifyDataSetChanged();
}
});
please help me.
My English is poor,sorry for it.
You want your data to be updated when the MainActivity is shown, right ?
You just have to call your getDataFromDB part in onResume() instead of onCreate()
EditActivity editActivity = new EditActivity();
editActivity.setOnClickDoneListener(new EditActivity.OnClickDoneListener() {
#Override
public void onClickDone() {
noteAdapter.notifyDataSetChanged();
}
});
What you are doing here is setting the value of OnClickDoneListener in a new instance of EditActivity that you will never use. Because when you use new Intent(MainActivity.this, EditActivity.class) to start the EditActivity it will create a new instance of EditActivity and your interface would be null.
I suggest you use android's Broadcast Receiver instead of a callback in this case. All you have to do is:
In MainActivity: You will need to instantiate a broadcast receiver. You need to register it onCreate or onStart and unregister it onStop or onDestory.
In EditAcitivity: You send a broadcast whenever you want to notify your MainActivity to update the list.
Check out this example:
https://riptutorial.com/android/example/18305/communicate-two-activities-through-custom-broadcast-receiver
I have one EditText which values i want to store with a button click in an array, in second Activity i want to display these values in Listview. I have some problems with storing and displaying values in another activity.
Use callback.
in ClassA with the stringList:
Create interface
MyCallback callback;
viod setCallback(MyCallback callback){
this.callback = callback;
}
viod onStop(){
callback = null;
}
interface MyCallback{
void doSomething(String string);
}
in ClassB:
implement MyCallback
public class ClassB implements ClassA.MyCallback
set reference in onCreate
ClassA classA = new ClassA();
classA.setCallback(this);
// override method doSomething
#override
void doSomething(String string){
//get your string from your EditText…
}
when the job is done inside class A call:
callback.doSomething(string);
destroy reference inside class B in onStop()
classA.onStop();
You can use an intent when starting the second Activity from your button click.
Intent intent = new Intent(this, SecondActivity.class);
intent.putStringArrayListExtra("EXTRA_ARRAY", arrayList);
startActivity(intent);
In your second activity...
List<String> arrayList = getIntent().getStringArrayListExtra("EXTRA_ARRAY");
you can use a static arrayList inside your activity like that :
class YourActivity extends AppCompatActivity{
public static ArrayList yourArray;
#Override
void onCreate(Bundle savedInstanceState){
.......
// you can use you array to display its content
}
}
and inside your button action do like that
botton.setOnClickListener(new OnClickListener{
#Override
void onClick(View view){
YourActivity.yourArray = this.arrayList;
startActivity(new Intent(getContext , YourActivity.class));
}
});
I have Act_01 (where I put value) and Act_02 (where I get value) but have declared these methods in a Extras class, getting value from Act_02 returns null value:
Act_01: (Where I want to pass the value Name to Act_02)
public class Act_01 extends Activity {
Extras cc_Extras;
Button btn1;
Intent intent;
String str_Name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_01);
cc_Extras = new Extras();
str_Name = "Buck";
btn1 = (Button) findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
cc_Extras.putExtras();
startActivity(intent);
}
});
}
}
Act_02: (Where I want ot receive value Name from Act_01 but the app crashes with null value)
public class Act_02 extends Activity {
Extras cc_Extras;
String str_Name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_02);
cc_Extras = new Extras();
if(getIntent() != null && getIntent().getExtras() != null)
{
cc_Extras.getExtras();
}
Toast.makeText(getApplicationContext(), "Name: "+str_Name, Toast.LENGTH_SHORT).show();
}
}
Extras: (Where I define the methods to put and get Extras)
public class Extras extends Activity {
String str_Name;
Intent intent;
public void putExtras() {
// TODO Auto-generated method stub
intent.putExtra("KEY_Name", str_Name);
}
public void getExtras() {
// TODO Auto-generated method stub
str_Name = getIntent().getExtras().getString("KEY_Name");
}
}
EDIT: I do not want to pass and get data directly between activities, I want to use the 3rd class (Extras.java) because I have too many activities having too many values between each other and want to sort of define them globally in Extras so that all my other activities can just call one method instead of getting and putting too many values in my activities.
Your app crashes not with a null value, but a null pointer reference because you created a new Activity manually
cc_Extras = new Extras();
Then called a lifecycle method on it
cc_Extras.getExtras()
Which calls getIntent(), but the Intent was never setup by the Android framework, and cc_Extras.getExtras() wouldn't have any of the data you wanted anyway in the second Activity because it was just created there, not from the first Activity.
Briefly, you should never make a new Activity, and your Extras class does not need to be an Activity in the first place (nor does it provide much benefit).
Just use the Intent object provided by the first Activity to start the second Activity, and get extras like normal. Don't overcomplicate your code. Regarding the title of the question, Intent and Bundle are already "another class" designed by Android for you to transfer data.
On both activities you are creating a new instances of Extras class means they dont hold the same value you can do this to transfer data from A to B
public class Act_01 extends Activity {
Button btn1;
Intent intent;
String str_Name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_01);
str_Name = "Buck";
btn1 = (Button) findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
intent = new Intent(Act_01.this, Act_02.class);
intent.putExtra("data", str_Name)
startActivity(intent);
}
});
}
}
And receieve data like this
public class Act_02 extends Activity {
String str_Name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_02);
// cc_Extras = new Extras();
if(getIntent() != null)
{
if (getIntent().getStringExtra("data") != null) {
Toast.makeText(Act_02.this, "Name: "+getIntent.getStringExtra("data"), Toast.LENGTH_SHORT).show();
}
}
}
}
Also you should consider using Activity Context instead of the application context
Ok! so here are the few things I might wanna suggest you to correct.
Changes needs to be done in the code.
You are not assigning anything to "intent" object , and you have passed a intent without assigning anything to it.
Your instance cc_Extra isn't doing anything in the activity1. You might wanna pass the "intent" object in your constructor of class like cc_Extras= new Extras(intent); and in the Extras class do the following- Intent intent;
Extras(Intent i)
{
this.intent=i;
}
In the activity2 you are creating the new Instance of Extras(). So according to your code it is going to be NULL by default. If you have done the changes from the previous step, you can create new instance by doing cc_Extras(getIntent());
Corrections in the code
1) In Extras class getExtras() method instead of str=getIntent() use str=intent.getExtras.getString().
2) In the activity2 you are not assigning anything to your String str_Name, so you need to return the string you got in getExtras() method. You can do it by changing the return type to String. Below is the sample code.
public String getExtras()
{
str_Name=intent.getExtras().getString("KEY_Name");
//OR
//str_Name=intent.getStringExtra("KEY_Name");
return str_Name;
}
3) By the doing this you need to catch this string in the activity2 by doing `
if(getIntent() != null && getIntent().getExtras() != null)
{
str_Name=cc_Extras.getExtras();
}`
4) Another thing is you must create intent like this-
Intent intent=new Intent(currentActivityName.this,anotherActivity2.class);
//then use the intent object
EDIT- Your code must look like this in the end...
Act1
public class Act_01 extends Activity {
Extras cc_Extras=null;
Button btn1;
String str_Name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_01);
str_Name = "Buck";
btn1 = (Button) findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//changes to do
Intent intent= new Intent(Act01.this,Act02.class);
cc_Extras= new Extras(intent);
cc_Extras.putExtras(str_Name);
//end
startActivity(intent);
}
});
}
}
Act02
public class Act_02 extends Activity {
Extras cc_Extras;
String str_Name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_02);
cc_Extras = new Extras(getIntent());
if(getIntent() != null && getIntent().getExtras() != null)
{
str_Name=cc_Extras.getExtras();
}
Toast.makeText(getApplicationContext(), "Name: "+str_Name, Toast.LENGTH_SHORT).show();
}
}
Extras class
public class Extras { //remove "extends Activity" because it is a class not a activity
String str_Name;
Intent intent;
Extras(Intent i)
{
this.intent=i;
}
public void putExtras(String str) {
// TODO Auto-generated method stub
str_Name=str;
intent.putExtra("KEY_Name", str_Name);
}
public String getExtras() {
// TODO Auto-generated method stub
str_Name = intent.getExtras().getString("KEY_Name");
return str_Name;
}
}
Above code will work just on String. You can extend the functionality if you want.
I hope this must work to get your code working!
I have espresso test which verifies that text is displayed:
public class InformationActivityTests {
#Rule
public ActivityTestRule<InformationActivity_> mInformationActivityTestRule =
new ActivityTestRule<InformationActivity_>(InformationActivity_.class) {
#Override
protected Intent getActivityIntent() {
Intent i = new Intent(getTargetContext(), InformationActivity_.class);
i.putExtra("INFORMATION", "Espresso");
return i;
}
};
#Test
public void textIsDisplayed() {
onView(withText("Espresso")).check(matches(isDisplayed()));
}
}
This test passes when Activity has following code:
#EActivity
public class InformationActivity extends AppCompatActivity {
#ViewById(R.id.information_view)
TextView informationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_information);
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information);
}
}
but fails when I "move" setContentView to #EActivity annotation:
#EActivity(R.layout.activity_information)
public class InformationActivity extends AppCompatActivity {
#ViewById(R.id.information_view)
TextView informationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information);
}
}
Error is:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.edu/com.edu.InformationActivity_}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Am I doing something wrong or is it an issue with espresso / android-annotations?
I've checked code generated by android-annotations when using #EActivity(R.layout.activity_information) and this is how onCreate looks like in generated class (InformationActivity_):
public void onCreate(Bundle savedInstanceState) {
OnViewChangedNotifier previousNotifier = OnViewChangedNotifier.replaceNotifier(onViewChangedNotifier_);
init_(savedInstanceState);
super.onCreate(savedInstanceState);
OnViewChangedNotifier.replaceNotifier(previousNotifier);
setContentView(R.layout.activity_information);
}
the problem is that it first calls super.onCreate (so onCreate from InformationActivity) where I handle intent and TextView and then it calls setContentView and this can't work like that.
The solution for this is what Be_Negative suggested, so using #AfterViews annotation. It also simplifies code a bit (I could remove onCreate method):
#EActivity(R.layout.activity_information)
public class InformationActivity extends AppCompatActivity {
#ViewById(R.id.information_view)
TextView informationView;
#AfterViews
void handleIntent() {
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information);
}
}
Your problem is that you are never initializing informationview
public class InformationActivity extends AppCompatActivity {
#ViewById(R.id.information_view)
TextView informationView; //<-- Null
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String information = intent.getStringExtra("INFORMATION");
informationView.setText(information); //<--STILL NULL
}
}
So you first will have to initialize that view.
I have three classActivity created. One is super class and other sub class and third is HomeActivity.
Code for super class is :
public class MyActivity extends Activity {
Button btnHome = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onHomeClick(View view) {
String LOG_TAG = "Akshar";
System.out.println("Hello11111");
btnHome = (Button) view;
Log.v(LOG_TAG, "index=" + btnHome);
}
}
and my subclass code is :
public class ChooseIsland extends MyActivity {
Button btn_home = null;
MyActivity ob1 = new MyActivity();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chooseiland);
addListenerOnButton();
}
private void addListenerOnButton() {
// TODO Auto-generated method stub
ob1.onHomeClick(btn_home);
}
}
Now I want to go on Home page when click so when I write ?
Intent intent = new Intent(this, HomeActivity.class);
There is no close operation as such in android. You should make sure you do not save anything in stack so whenever you are traversing from one activity to other, make sure you use intent flags to clear history or top of stack and then call finish.
finish() will close the current activity and the previous activity will come to foreground.
Generally to we write finish() method to close activity.