Now I'm studying Threads and my task is to make a counter, which will add number from 0 to 9 to TextView with the help of Loader. Of course, I know that it isn't the best variant to use Loader for such tasks, but I'd like to understand how does it work.
So, I have the following code:
package asus.example.com.exercise4;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class LoaderActivity extends AppCompatActivity {
private TextView counter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_threads);
Button startButton = findViewById(R.id.start_button);
Button cancelButton = findViewById(R.id.cancel_button);
startButton.setOnClickListener(listener);
cancelButton.setOnClickListener(listener);
counter = findViewById(R.id.counter);
}
private View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.start_button:
getSupportLoaderManager().initLoader(0, null, new LoaderClass());
break;
case R.id.cancel_button:
break;
}
}
};
#SuppressLint("StaticFieldLeak")
class AsyncTaskLoaderClass extends AsyncTaskLoader<Void>{
AsyncTaskLoaderClass(#NonNull Context context) {
super(context);
}
#Nullable
#Override
public Void loadInBackground() {
for (int i = 0; i<10;i++){
counter.setText(i);
SystemClock.sleep(500);
}
return null;
}
}
private class LoaderClass implements LoaderManager.LoaderCallbacks<Void>{
#NonNull
#Override
public Loader<Void> onCreateLoader(int i, #Nullable Bundle bundle) {
return new LoaderActivity.AsyncTaskLoaderClass(LoaderActivity.this);
}
#SuppressLint("SetTextI18n")
#Override
public void onLoadFinished(#NonNull Loader<Void> loader, Void aVoid) {
counter.setText("Done!");
}
#Override
public void onLoaderReset(#NonNull Loader<Void> loader) {
}
}
}
When I run the project I have a runtime error:
java.lang.IllegalArgumentException: Object returned from onCreateLoader must not be a non-static inner member class: AsyncTaskLoaderClass{eed39bf id=0}
Yes, I understand, that it means that AsyncTaskLoaderClass should be in another file or static, but in such case I won't have an opportunity to add text to textview. So, how can I solve this problem?
UPD
I changed the code in clicking start button in such way:
case R.id.start_button:
Loader loader = getSupportLoaderManager().initLoader(0, null, LoaderActivity.this);
loader.forceLoad();
Log.i(TAG, "Button start clicked");
break;
And now each time in the loop I have the following error:
E/e.com.exercise: Invalid ID 0x00000009.
E/EventBus: Could not dispatch event: class asus.example.com.exercise4.LoaderActivity$MyAsyncTaskLoader$ProgressEvent to subscribing class class asus.example.com.exercise4.LoaderActivity
android.content.res.Resources$NotFoundException: String resource ID #0x9
UPD 2
Finally fixed the problem in the following way:
Was
counter.setText(i);
Now
counter.setText(""+i);
Probably I don't understrand why it works, but it works
Make the Activity implement LoaderCallbacks. Also a Loader retrieves one particular value in its onLoadFinished callback, and it should return the retrieved (loaded) item as a result.
To change what value is being loaded by a Loader, you're supposed to restart the loader with a new argument bundle, and pass in the parameters so that it knows what it is doing.
Then again, you are trying to create something like "publishProgress" in AsyncTask; Loaders cannot do that out of the box, and need some variant of "sending an event" (handler threads if you are adventurous, but most likely an event bus, see implementation 'org.greenrobot:eventbus:3.1.1').
TL;DR: use EventBus for this.
public class LoaderActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Void> {
private TextView counter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_threads);
Button startButton = findViewById(R.id.start_button);
Button cancelButton = findViewById(R.id.cancel_button);
counter = findViewById(R.id.counter);
startButton.setOnClickListener((view) -> {
getSupportLoaderManager().initLoader(0, null, LoaderActivity.this);
});
cancelButton.setOnClickListener((view) -> {
// do nothing, apparently
});
EventBus.getDefault().register(this);
}
#Override
protected void onDestroy() {
EventBus.getDefault().unregister(this);
super.onDestroy();
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onLoaderProgressEvent(MyAsyncTaskLoader.ProgressEvent event) {
counter.setText("" + event.getNumber());
}
#NonNull
#Override
public Loader<Void> onCreateLoader(int i, #Nullable Bundle bundle) {
return new MyAsyncTaskLoader(LoaderActivity.this);
}
#SuppressLint("SetTextI18n")
#Override
public void onLoadFinished(#NonNull Loader<Void> loader, Void aVoid) {
counter.setText("Done!");
}
#Override
public void onLoaderReset(#NonNull Loader<Void> loader) {
}
public static class MyAsyncTaskLoader extends AsyncTaskLoader<Void> {
public static class ProgressEvent {
private final int number;
public ProgressEvent(int number) {
this.number = number;
}
public int getNumber() { return number; }
}
public MyAsyncTaskLoader(#NonNull Context context) {
super(context);
}
#Nullable
#Override
public Void loadInBackground() {
for (int i = 0; i<10;i++){
EventBus.getDefault().post(new ProgressEvent(i));
SystemClock.sleep(500);
}
return null;
}
}
}
Your are using inner AsyncTaskLoaderClass in Activity class. Inner class holds the reference of Outer class. That means your AsyncTaskLoaderClass may hold Activity reference in some cases. Make your inner class static.
You have 2 solutions. Make AsyncTaskLoaderClass a separate class file or make AsyncTaskLoaderClass a static class.
make textview public static like this public static TextView counter;
Related
I'm sure it's going to be a something very obvious that my stupid self couldn't find even after staring at the code for an hour.
I am trying to call the updateImages method in FragmentHome from HomeActivity. I have also created an instance of the class in onCreate but for reasons of my primitive coding knowledge, I am not able to call it. Any help would be greatly appreciated :)
Class that contains said method:
package com.example.youtubethumbnailapp;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.squareup.picasso.Picasso;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import static android.app.Activity.RESULT_OK;
public class FragmentHome extends Fragment {
private FragmentHomeListener listener;
public interface FragmentHomeListener{
void onInputHomeSent(ArrayList<Uri> input);
}
private ImageView video1;
private ImageView video2;
private ImageView video3;
private ImageView video4;
private ImageView video5;
private ImageView video6;
private ImageView video7;
private ImageView video8;
private ImageView video9;
private ImageView video10;
private ImageView addImageButton;
public Uri imageUri;
ArrayList<Uri> uriArrayList = new ArrayList<Uri>();
ArrayList<ImageView> imageViews = new ArrayList<ImageView>();
private int imagesSelected = 0;
#Nullable
#org.jetbrains.annotations.Nullable
#Override
public View onCreateView(#NonNull #org.jetbrains.annotations.NotNull LayoutInflater inflater, #Nullable #org.jetbrains.annotations.Nullable ViewGroup container, #Nullable #org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home,container,false);
//initialize variables
video1 = v.findViewById(R.id.video1);
imageViews.add(video1);
video2 = v.findViewById(R.id.video2);
imageViews.add(video2);
video3 = v.findViewById(R.id.video3);
imageViews.add(video3);
video4 = v.findViewById(R.id.video4);
imageViews.add(video4);
video5 = v.findViewById(R.id.video5);
imageViews.add(video5);
video6 = v.findViewById(R.id.video6);
imageViews.add(video6);
video7 = v.findViewById(R.id.video7);
imageViews.add(video7);
video8 = v.findViewById(R.id.video8);
imageViews.add(video8);
video9 = v.findViewById(R.id.video9);
imageViews.add(video9);
video10 = v.findViewById(R.id.video10);
imageViews.add(video10);
addImageButton = v.findViewById(R.id.changeViewButton);
addImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
choosePicture();
}
});
return v;
}//end of onCreate
private void choosePicture() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, 1);
}
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==1 && resultCode==RESULT_OK && null != data && data.getData()!=null){
imageUri = data.getData();
addPicture();
uriArrayList.add(imageUri);
imagesSelected++;
}
}
#Override
public void onAttach(#NonNull #NotNull Context context) {
super.onAttach(context);
if (context instanceof FragmentHomeListener){
listener = (FragmentHomeListener) context;
} else {
throw new RuntimeException(context.toString()
+ "must implement FragmentHomeListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
//this is the method I want to call
public void updateImages(ArrayList<Uri> imagesArrayList){
for (int i = 0; i < imagesArrayList.size(); i++){
Picasso.get()
.load(imagesArrayList.get(i))
.fit().centerCrop()
.into(imageViews.get(i));
}
}
private void addPicture(){
Picasso.get()
.load(imageUri)
.fit().centerCrop()
.into(imageViews.get(imagesSelected));
}
private void dataSent(){
listener.onInputHomeSent(uriArrayList);
}
}
Class where I want to call the method from:
package com.example.youtubethumbnailapp;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class HomeActivity extends AppCompatActivity implements FragmentHome.FragmentHomeListener, FragmentHistory.FragmentHistoryListener, FragmentSuggested.FragmentSuggestedListener {
private ImageView homeButton;
private ImageView historyButton;
private ImageView playButton;
private Fragment fragmentHome;
private Fragment fragmentHistory;
private Fragment fragmentSuggested;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
homeButton = findViewById(R.id.homeButton);
historyButton = findViewById(R.id.historyButton);
playButton = findViewById(R.id.playButton);
fragmentHome = new FragmentHome();
fragmentHistory = new FragmentHistory();
fragmentSuggested = new FragmentSuggested();
switchToFragmentHome();
homeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switchToFragmentHome();
}
});
historyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switchToFragmentHistory();
}
});
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switchToFragmentSuggested();
}
});
}//end of onCreate
public void switchToFragmentHome(){
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().replace(R.id.flFragment, fragmentHome).commit();
}
public void switchToFragmentSuggested(){
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().replace(R.id.flFragment, fragmentSuggested).commit();
}
public void switchToFragmentHistory(){
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().replace(R.id.flFragment, fragmentHistory).commit();
}
#Override
public void onInputHistorySent(ArrayList<Uri> input) {
//I want to call it from here
}
#Override
public void onInputHomeSent(ArrayList<Uri> input) {
}
#Override
public void onInputSuggestedSent(ArrayList<Uri> input) {
}
}
Since I have instantiated the class, I tried fragmentHome.update but it doesn't show up.
you are creating new instance of fragment. Please check below code:
FragmentHome fragmentHome = new FragmentHome();
You should use it like this:
fragmentHome = new FragmentHome();
Currently, your updateImages method is part of an instance of the class FragmentHome. Since the method doesn't seem to depend on anything, e.g., state, you can make the method static as follows:
public static void updateImages(//args...){
// Your method here
}
Within HomeActivity, you can access this static inner method directly as:
FragmentHome.updateImages(//args...);
P.S.: At the moment, you are likely getting a Non-static method 'updateImages()' cannot be referenced from a static context error.
Note that creating and using updateImages() in this manner is not good practice. It is not "wrong", but it is not efficient in the long run and can cause bugs. (E.g., even if you just declared the method static, you'd likely get a NullPointerException because updateImages() contains a reference to imageViews, an object inside FragmentHome, which may not have been initialized when the method is called in HomeActivity.)
If possible, you should put the independent method updateImages() in a separate utilities class, such that your UI code is as separate from your logic code as possible. This is called "separation of concerns".
I see that you need to use Picasso to set a source image to an ImageView. To do this, you could pass in the ImageView as an argument into the method (disclaimer: if it makes sense for your use case; if it is not going to leak context; etc.), so that the updateImages() method doesn't contain a reference to the imageViews ArrayList that sits in your FragmentHome. Also note that imageViews is currently private, since you've not declared it public.
If you employ this method, your updateImages() or other methods can be reused with higher generality. But of course, there are cases where you just want a wrapper for a method you just can't make very generalized, and that's okay too.
I am having some trouble. I followed every guide online showing how to override a parent method in a child class. I have done everything I was told to do, yet my child function does nothing.
My MainActivity(Parent) class:
package com.example.flashcards;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
DatabseHelper DB = new DatabseHelper(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
changeText();
changeText2();
};
public void changeText(){}
public void changeText2(){}
String [] columns = new String[] {
DatabseHelper.FLASHCARD_QUESTION,
DatabseHelper.FLASHCARD_ANSWER
};
#Override
public void onClick(View v) {
}
}
My child class (TextC)
package com.example.flashcards;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class TextC extends MainActivity {
#Override
public void changeText() {
super.changeText();
final String[] revertText = {"H2O", "What elements does water consist of?"};
final TextView textChange = findViewById(R.id.flashcard1);
Button change = findViewById(R.id.answer1);
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int random = (int) (Math.random() * revertText.length);
textChange.setText(revertText[random]);
}
});
}
public void changeText2() {
super.changeText2();
final String[] revertText = {"2,200° F", "How hot does lava get?"};
final TextView textChange = findViewById(R.id.flashcard2);
Button change = findViewById(R.id.answer2);
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int random = (int) (Math.random() * revertText.length);
textChange.setText(revertText[random]);
}
});
}
}
My changeText() function does nothing. I am not getting any errors, so I can not tell what I am doing wrong. Do I need to create an onCreate method for the child class? But I am extending MainActivity which has it.
Any ideas on why my method overriding is not working?
With inheritance and overriding concepts, you need to override onCreate function in your child class. And from that overridden method, you can make a call to super.onCreate or you can do this.chnageText and this.changeText2 from child class.
Otherwise when you call onCreate function, it will call changeText and changeText2 from super class only.
In your child class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.changeText();
this.changeText2();
};
Modify parent class
package com.example.flashcards;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
DatabseHelper DB = new DatabseHelper(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//changeText(); freeze or remove these callings
//changeText2();
};
public void changeText(){}
public void changeText2(){}
}
And add some code to your child class
package com.example.flashcards;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class TextC extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
changeText();
changeText2();
};
#Override
public void changeText() {
super.changeText();
final String[] revertText = {"H2O", "What elements does water consist of?"};
final TextView textChange = findViewById(R.id.flashcard1);
Button change = findViewById(R.id.answer1);
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int random = (int) (Math.random() * revertText.length);
textChange.setText(revertText[random]);
}
});
}
public void changeText2() {
super.changeText2();
final String[] revertText = {"2,200° F", "How hot does lava get?"};
final TextView textChange = findViewById(R.id.flashcard2);
Button change = findViewById(R.id.answer2);
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int random = (int) (Math.random() * revertText.length);
textChange.setText(revertText[random]);
}
});
}
}
In the above method there is no point declare changeText(); and changeText2(); in parent activity. For the sake of reusability, we can use abstract classes and methods.
Do some changes to your parent activity as you see below.
public abstract class MainActivity extends AppCompatActivity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
changeText(); // they dont have default implimentation in parent so it will be invoked from child class where these methods implimented
changeText2();
};
public abstract void changeText(); //there is no default implimentation
public abstract void changeText2();
}
And in child activity, you have to implement those methods.
public class TextC extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//changeText(); no need to call these methods bcz its already called in parent onCreate()
//changeText2();
};
#Override
public void changeText() {
super.changeText();
final String[] revertText = {"H2O", "What elements does water consist of?"};
final TextView textChange = findViewById(R.id.flashcard1);
Button change = findViewById(R.id.answer1);
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int random = (int) (Math.random() * revertText.length);
textChange.setText(revertText[random]);
}
});
}
public void changeText2() {
super.changeText2();
final String[] revertText = {"2,200° F", "How hot does lava get?"};
final TextView textChange = findViewById(R.id.flashcard2);
Button change = findViewById(R.id.answer2);
change.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int random = (int) (Math.random() * revertText.length);
textChange.setText(revertText[random]);
}
});
}
}
There is two arrows as you see in picture ..
one indicate to Activities in my project
other one indicate to recommended activity to declare in manifest ..
but there is no recommended activity except " StreamingActivity "
when i run my application ,, application show me that message " Unfortunately , application has stopped "
this code for publisheractivity
package khaabbas.huthaifa.com.talk_listen;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import com.red5pro.streaming.R5Connection;
import com.red5pro.streaming.R5Stream;
import com.red5pro.streaming.R5StreamProtocol;
import com.red5pro.streaming.config.R5Configuration;
import com.red5pro.streaming.source.R5Camera;
import com.red5pro.streaming.source.R5Microphone;
//import android.graphics.Camera;
public class PublishFragment extends android.support.v4.app.Fragment implements SurfaceHolder.Callback {
public static android.support.v4.app.Fragment newInstance() {
PublishFragment fragment = new PublishFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
public PublishFragment() {
// Required empty public constructor
}
public R5Configuration configuration;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
configuration = new R5Configuration(R5StreamProtocol.RTSP, "localhost", 8554, "live", 1.0f);
configuration.setLicenseKey("NBZF-UFM2-GCEP-OUYZ");
configuration.setBundleID(getActivity().getPackageName());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_publish, container, false);
return v;
}
protected Camera camera;
protected boolean isPublishing = false;
protected R5Stream stream;
private void preview() {
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
SurfaceView surface = (SurfaceView) getActivity().findViewById(R.id.surfaceView);
surface.getHolder().addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
}
catch(Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
#Override
public void onResume() {
super.onResume();
preview();
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Button publishButton = (Button) getActivity().findViewById(R.id.publishButton);
publishButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onPublishToggle();
}
});
}
private void onPublishToggle() {
Button publishButton = (Button) getActivity().findViewById(R.id.publishButton);
if(isPublishing) {
stop();
}
else {
start();
}
isPublishing = !isPublishing;
publishButton.setText(isPublishing ? "stop" : "start");
}
public void start() {
camera.stopPreview();
stream = new R5Stream(new R5Connection(configuration));
stream.setView((SurfaceView) getActivity().findViewById(R.id.surfaceView));
R5Camera r5Camera = new R5Camera(camera, 320, 240);
R5Microphone r5Microphone = new R5Microphone();
stream.attachCamera(r5Camera);
stream.attachMic(r5Microphone);
stream.publish("red5prostream", R5Stream.RecordType.Live);
camera.startPreview();
}
public void stop() {
if(stream != null) {
stream.stop();
camera.startPreview();
}
}
#Override
public void onPause() {
super.onPause();
if(isPublishing) {
onPublishToggle();
}
}
}
Remove both this activity because u used only single activity it define activity and two other is fragment.
<activity android:name=".S"/>
<activity android:name=".Sub"/>
and fragment call used below code..
Fragment fragment = new HomeFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();
No need to declare fragment on manifest, remove fragment declaration from manifest because you are declare fragment within section in manifest file.
I have java class called Second.java which has a method called toast_method().
My question is, How can i call the toast_method() from the Second.java and then display the toast message in the app?
I tried the following code but it's not working
Second.java
package com.example.callmethod;
import android.content.Context;
import android.widget.Toast;
public class Second {
Context context;
public Second(Context context) {
this.context = context;
}
public void toast_method() {
Toast.makeText(context, "Hello", Toast.LENGTH_SHORT).show();
}
}
MainActivity.java
package com.example.callmethod;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
private Second myotherclass;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Calling the method from Second Class
myotherclass.toast_method();
}
}
Thanks
You are nearly there! Only missing the vital instantiation of the second class:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Calling the method from Second Class
myotherclass = new Second(this); // <----- this
myotherclass.toast_method();
}
do it in onCreate Like this
Second second =new Second(this);
second.toast_method();
Easy one ^^
you have to extends Activity to use context in the activity
public class operation extends Activity {
// normal toast
//you can change length
public static void toast(String toastText, Context contex) {
Toast.makeText(contex, toastText, Toast.LENGTH_LONG).show();
}
// Empty Toast for Testing
public static void emptyToast(Context contex) {
Toast.makeText(contex, R.string.EmptyText, Toast.LENGTH_LONG).show();
}
}
now ... in your activity only call function
operation.toast("Your Text",currentClass.this);
Example :
public class currentClass extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
operation.toast("Hello",currentClass.this);
}
}
EDIT please see Observer Observables implementing issue - It seems I was overriding methods that didn't need to be and not calling setChanged(); before notify();
I've been reading up on the Observer Pattern for keeping my UI up to date but I still can't see the use for it.. Even if in my particular object notifies my MainActivity then runs the update(); method I still wouldn't be able to use the Pet object to pull the update values as the object is created in Oncreate...and I just can't create a new object because then the variables will be different..this is my implementation and it doesn't seem to work.
Observer/MainActivity
package com.grim.droidchi;
import java.util.Observable;
import java.util.Observer;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements Observer, OnClickListener {
private static final String TAG = "VPET";
private static final String APP_PREFS = "VPET";
private static final int REQUEST_CODE = 1;
Boolean isAlive = false;
TextView happiness_display, health_display, hunger_display, level_display;
Button PunchPet, UpdateHunger;
public static Pet pet = new Renamon();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences settings = getSharedPreferences("APP_PREFS",
MODE_PRIVATE);
WebView myWebView = (WebView) findViewById(R.id.pet_display);
myWebView.loadUrl("file:///android_asset/renamon.gif");
myWebView.setInitialScale(10000);
myWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
PunchPet = (Button) findViewById(R.id.PunchPet);
UpdateHunger = (Button) findViewById(R.id.UpdateHunger);
final TextView hunger_display = (TextView) findViewById(R.id.hunger_display);
TextView happiness_display = (TextView) findViewById(R.id.happiness_display);
TextView level_display = (TextView) findViewById(R.id.level_display);
TextView health_display = (TextView) findViewById(R.id.health_display);
hunger_display.setText(Integer.toString(pet.getHunger()));
health_display.setText(Integer.toString(pet.getHP()));
level_display.setText(Integer.toString(pet.getLVL()));
happiness_display.setText(Integer.toString(pet.getHappy()));
Intent intent = new Intent(this, Gameloop.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getBaseContext(), REQUEST_CODE, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + (5 * 1000), 1800000, pendingIntent);
// 1800000 ms = 30 mins
pet.feed();
pet.addObserver(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
protected void onPause() {
super.onPause();
}
#Override
public void update(Observable o, Object data) {
hunger_display.setText(Integer.toString(pet.getHunger()));
health_display.setText(Integer.toString(pet.getHP()));
level_display.setText(Integer.toString(pet.getLVL()));
happiness_display.setText(Integer.toString(pet.getHappy()));
Log.d(TAG, "UPDATED FROM OBSERVER");
}
#Override
public void onClick(View v) {
if (v == PunchPet) {
pet.setHP(500);
Toast.makeText(getApplicationContext(), "PUNCHPET", Toast.LENGTH_SHORT).show();
health_display.setText(Integer.toString(pet.getHP()));
}else {
}
}
}
Observable/Pet
package com.grim.droidchi;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;
import android.util.Log;
public class Pet extends Observable implements PetInterface {
protected Set<Observer> observers;
private static final String TAG = "VPET";
private int Health = 100;
#Override
public void addObserver(Observer o) {
observers.add(o);
super.addObserver(o);
}
#Override
public void notifyObservers() {
observers.notify();
super.notifyObservers();
}
#Override
public synchronized void deleteObserver(Observer o) {
observers.remove(o);
super.deleteObserver(o);
}
private int Happiness = 10;
private int Level = 1;
private int Hunger = 0;
private int Exp = 0;
private String Name;
private Boolean isAlive = true;
private Boolean isSick = false;
public void setHP(int hp) {
this.Health = hp;
notifyObservers(hp);
}
public void setLVL(int lvl) {
this.Level = lvl;
notifyObservers(lvl);
}
public void setXP(int xp) {
this.Exp = xp;
notifyObservers(xp);
}
public void setHunger(int hunger) {
this.Hunger = hunger;
notifyObservers(hunger);
}
public void setHappy(int happy) {
this.Happiness = happy;
notifyObservers(happy);
}
public int getHP() {
return Health;
}
public int getLVL() {
return Level;
}
public int getXP() {
return Exp;
}
public int getHunger() {
return Hunger;
}
public int getHappy() {
return Happiness;
}
public boolean isAlive() {
return isAlive;
}
public boolean isSick() {
return isSick;
}
#Override
public void sleep() {
// TODO Auto-generated method stub
}
#Override
public void clean() {
// TODO Auto-generated method stub
}
#Override
public void feed() {
Log.d(TAG, "FEEDING FROM INTERFACE THING");
}
#Override
public void passtime() {
}
}
First, I wouldn't recommend overriding addObserver or removeObserver in your observable object. The API does a really good job of implementing this (unless you want some specific functionality).
Second, the method notifyObservers() is overloaded so that you can pass it an object, IE notifyObservers(Object obj). If you pass it your Pet, notifyObservers(this), then you will have a reference to your Pet object that is being observed.
I think this is your question but please correct me if I am wrong.
EDIT: To clarify, my answer is contingent upon you using the Observable class in the Java API here.
Upon further review, you should already have a reference to the Pet object that called the update method of the Observer
Your pet is not accessible in other methods because its not defined at global level.
You should define Pet pet = new Renamon(); outside of onCreate method.