I have two class. One of them is activity. I have a function in activity class and try to call in other class. In function i can't use view functions(setContentView, findViewById) These functions works well in onCreate. I try to change image position and size.
function definition like:
public void changePosition(int x, int y, int z){
}
I always got this error. Why these functions works only in onCreate?
Logcat:
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.project.scan, PID: 26122
java.lang.NullPointerException
at android.app.Activity.findViewById(Activity.java:1970)
at com.example.project.scan.ProjectActivity.changePosition(ProjectActivity.java:255)
at com.example.project.scan.Model$1.handleMessage(Model.java:145)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
ProjectActivity.java:255 :
image = (ImageView)findViewById(R.id.im);
Model.java:145:
myActivity.changePosition(x,y,z);
Seems like you've instantiated your myActivity with new. Never instantiate activities with new as they won't be properly initialized for anything you'd use an activity for.
Use an Intent to instantiate activities with correct lifecycle initialization, or pass the activity reference (this in an activity) to other methods that need to call methods in the activity.
You can pass the Activity reference
use below code:
public class YourClass
{
Activity activity ;
public YourClass(Activity _activity)
{
activity = _activity ;
}
}
Then use it as :
classObject.changePosition(x,y,z);
Now you can use method like :
activity.findViewById(id)
Don't forget to pass the Activity reference as:
YourClass classObject = new YourClass(ProjectActivity.this);
Hope it helps ツ
Related
I often need user interaction (dialogs) from custom classes that aren't subclasses of Activity or Fragment. Here's an example of how I'm currently doing this. I open the dialog from the fragment manager of the fragment that created the custom class, and I use a small inner class as the target so I can get the dialog result. This keeps all the related code in one place, as opposed to putting onActivityResult in the parent fragment:
public class DocumentViewer extends RelativeLayout {
public void deleteAnnotations() {
DialogFragment dialog = new DialogFragment();
Bundle args = new Bundle();
args.putString("title", this.app.getString(R.string.DELETE_ANNOTATIONS));
args.putString("message", this.app.getString(R.string.CONFIRM_DELETE_ANNOTATIONS));
args.putString("button1Text", this.app.getString(R.string.BUTTON_DELETE));
args.putString("button2Text", this.app.getString(R.string.BUTTON_CANCEL));
dialog.setArguments(args);
DocumentViewerAlertListener listener = new DocumentViewerAlertListener();
listener.canvas = this.canvas;
dialog.setTargetFragment(listener, R.id.confirmDelete);
dialog.show(this.fragment.getFragmentManager(), "confirmDelete");
}
public static class DocumentViewerAlertListener extends ALFragment {
public ALCanvas canvas;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if ((requestCode == R.id.confirmDelete)&&(resultCode == 1)) {
this.canvas.clearItems();
}
}
}
}
Unfortunately, in Android O, the dialog.show line crashes with this stack trace:
09-20 14:06:12.852 24301-24301/com.bizname.appname E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.bizname.appname, PID: 24301
java.lang.IllegalStateException: Fragment ALAlert{1ace4cd #8 confirmDelete} declared target fragment DocumentViewerAlertListener{7e21182} that does not belong to this FragmentManager!
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1209)
at android.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1549)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1611)
at android.app.BackStackRecord.executeOps(BackStackRecord.java:807)
at android.app.FragmentManagerImpl.executeOps(FragmentManager.java:2394)
at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2189)
at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2142)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2049)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:718)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
It makes sense that the fragment manager I'm using doesn't know about this inner class, but what's the alternative? I tried using the inner class as the fragment manager...
dialog.show(listener.getFragmentManager(), "confirmDelete");
...and there was no crash, but the dialog didn't appear, perhaps because the listener fragment is never displayed.
I'm open to either a quick fix for my current approach, or a different approach that accomplishes the same thing (but would prefer a quick fix!).
While writing out the question, I had an idea based on "the listener fragment is never displayed." I added this line before showing the dialog:
this.fragment.getFragmentManager().beginTransaction().add(listener, "confirmDelete").commit();
I assume this lets the fragment manager know about my listener fragment, so it doesn't throw the exception.
This seems like an easy and logical fix, but I'm still open to other approaches.
I'm trying to start a Fragment inside my RecycleAdapter but when cast my Context with the AppCompatActivity the App crashed and inside logcat I got the message that android.app.Application cannot be cast to android.support.v7.app.AppCompatActivity.
here is my onClickListener inside RecycleAdapter.
holder.ItemClickButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction;
Toast.makeText(CTX,"Row Clicked id : "+homeCycleDataProvider.getId(),Toast.LENGTH_SHORT).show();
ItemsFragment fragobj = new ItemsFragment();
FragmentManager manager = ((AppCompatActivity) CTX).getSupportFragmentManager();
fragmentTransaction = manager.beginTransaction()
fragmentTransaction.replace(R.id.main_container, fragobj);
fragmentTransaction.commit();
}
});
here is my Adapter Initialization where I pass the context.
adapter = new ItemsRecycleAdapter(arrayList,getContext());
LOGCAT.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.a1appstudio.sabirhossain.xpresdelivery, PID: 3109
java.lang.ClassCastException: android.app.Application cannot be cast to android.support.v7.app.AppCompatActivity
at com.a1appstudio.sabirhossain.xpresdelivery.ItemsListViewPackage.ItemsRecycleAdapter$1.onClick(ItemsRecycleAdapter.java:66)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
A context is not always an Activity, even when you're in an Activity. It could be an Application, or a wrapper around another context. It's almost always wrong to cast a Context to an Activity. If you absolutely need one, you should pass in an Activity as a parameter, rather than a Context. Or better yet, pass in the support fragment manager directly rather than the activity, since that's all you need it for.
adapter = new ItemsRecycleAdapter(arrayList,getActivity());
you can try this
if (context instanceof MainActivity ) {
MainActivity myActivity = (MainActivity)context;
myActivity.getSupportFragmentManager();
}
I am aware there are many forms on StackOverflow about this very topic but none of the fixed worked for me.
When I run the code:
muteText.setText("Testing")
I get an error.
MainActivity.java
//Class Variables
Button startTime;
Button endTime;
TextView muteTime;
TextView unmuteTime;
int hour;
int minute;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Define Variables
startTime = (Button)findViewById(R.id.startButton);
endTime = (Button)findViewById(R.id.endTime);
muteTime = (TextView)findViewById(R.id.muteText);
Log.i("SchedMute", "muteTime: " + muteTime.getText().toString());
unmuteTime = (TextView)findViewById(R.id.unmuteTime);
//Button Listeners
startTime.setOnClickListener(this);
endTime.setOnClickListener(this);
//--\\
hour = 0;
minute = 0;
}
public void onClick(View v){
int id = v.getId();
if(id == R.id.startButton){ //Selecting time 2 Mute phone
showTimePickerDialog(v);
}
}
public void setStartTime(){
muteTime.setText("Testing Testing 123");
}
(Error occurs in last Method (setStartTime))
I am calling the method in another class by doing so:
MainActivity activity = new MainActivity();
activity.setStartTime();
I spend a good 30 minutes trying to figure this one out.
Error:
07-29 12:29:44.034 19958-19958/myApp.com.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: myApp.com.app, PID: 19958
java.lang.NullPointerException
at myApp.com.app.MainActivity$TimePickerFragment.onTimeSet(MainActivity.java:96)
at android.app.TimePickerDialog.tryNotifyTimeSet(TimePickerDialog.java:223)
at android.app.TimePickerDialog.onClick(TimePickerDialog.java:173)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:170)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5678)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(Native Method)
MainActivity activity = new MainActivity();
You can NOT correctly create an instance of an Activity by using new. Never attempt to do this, it will not give you the behaviour you expected.
If you need to call a method in an Activity from a Fragment that is attached to it, you should used the approved approach of using a 'callbacks' interface.
See the following for Communicating with Other Fragments - even though it is about communicating with other Fragments, it is also the way a Fragment should communicate with the Activity it is attached to.
You call to setText before the Activity finished it creation. You need to call the function from the new Activity onCreate().
You should never call the constructor of an Activity. If you do, none of its activity lifecycle will occur. I'm guessing you're doing that in the time picker dialog, you should make that activity be a listener (or pass in an anonymous inner class listener) to handle the set time.
I need to start another activity from the onPosExecute method of the AsyncTask. The AsyncTask is a seperate class and not in any activity class.
I have used an interface to do so. The codes are:
This is the onPostExecute() method
#Override
protected void onPostExecute(String json) {
Log.v("JSON", json);
Log.v("updateUI",""+updateUI);
updateUI.changeActivity();
}
This is the interface
public interface UpdateUIListener {
public void changeActivity();
}
And this is the part of the activity class where the interface is implemented
#Override
public void changeActivity() {
Intent blah=new Intent(this,SplashActivity.class);
startActivity(blah);
finish();
}
When I run the code, a null pointer exception shows up, at the line
Intent blah=new Intent(this,SplashActivity.class);
My stacktrace is:
java.lang.NullPointerException
at android.content.ContextWrapper.getPackageName(ContextWrapper.java:135)
at android.content.ComponentName.<init>(ComponentName.java:75)
at android.content.Intent.<init>(Intent.java:3546)
at com.autofoyer.SignUpActivity.changeActivity(SignUpActivity.java:79)
at com.autofoyer.common.MyClientTask.onPostExecute(MyClientTask.java:73)
at com.autofoyer.common.MyClientTask.onPostExecute(MyClientTask.java:23)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5099)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:803)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:570)
at dalvik.system.NativeStart.main(Native Method)
I need to know what is causing and How to solve the null point exception. I need to start and activity from the onPostExecute method. Thanks in advance!
You probably instantiate updateUI with new SplashActivity() or similar. You can't do that. Instead you have to pass a Context into your AsyncTask and use that to call startActivity() . You probably start the AsyncTask from some Activity, so just pass that Activity as a Context when instantiating the AsyncTask.
When I press the Home button, the app should be paused, save all state and work fine.
Instead I get this error:
java.lang.RuntimeException: Unable to
pause activity
{be.test.tester/be.test.tester.DataScreen}:
java.lang.IllegalStateException:
Derived class did not call
super.onSaveInstanceState() at
android.app.ActivityThread.performPauseActivity(ActivityThread.java:3641)
at
android.app.ActivityThread.performPauseActivity(ActivityThread.java:3598)
at
android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3574)
at
android.app.ActivityThread.access$2500(ActivityThread.java:136)
at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:2186)
at
android.os.Handler.dispatchMessage(Handler.java:99)
at
android.os.Looper.loop(Looper.java:143)
at
android.app.ActivityThread.main(ActivityThread.java:5068)
at
java.lang.reflect.Method.invokeNative(Native
Method) at
java.lang.reflect.Method.invoke(Method.java:521)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at
dalvik.system.NativeStart.main(Native
Method)
Caused by:
java.lang.IllegalStateException:
Derived class did not call
super.onSaveInstanceState() at
android.view.View.dispatchSaveInstanceState(View.java:6087)
at
android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:1207)
at
android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:1207)
at
android.view.View.saveHierarchyState(View.java:6068)
at
com.android.internal.policy.impl.PhoneWindow.saveHierarchyState(PhoneWindow.java:1475)
at
android.app.Activity.onSaveInstanceState(Activity.java:1106)
at
android.app.Activity.performSaveInstanceState(Activity.java:1056)
at
android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1289)
at
android.app.ActivityThread.performPauseActivity(ActivityThread.java:3623)
... 12 more
My activity reacts on touch:
public class DataScreen extends Activity implements OnGestureListener{
I'm getting some extra's from the intent:
totUsage = Integer.parseInt(getIntent().getStringExtra("extraTotUsage"));
limit = Integer.parseInt(getIntent().getStringExtra("extraLimit"));
Bundle bundle = getIntent().getExtras();
mylist = (ArrayList<HashMap<String, String>>) bundle.get("extraMyList");
A custom view is showing data (canvas). When you scroll on screen, data changes in custom view (set, get method) and redraws itself.
I don't really manage the onSaveInstanceState here, don't really know if I have to.
My app is onTop of the stack, because of:
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
I don't understand the error.
You should override onSaveInstanceState and call its super method like shown below. At least it helped me with the same problem.
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// your stuff or nothing
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// your stuff or nothing
}
I've just been dealing with this problem. In my app the main activity allows a second activity to be called to display info/instructions etc, it also has a surface view that draws the runtime element of the app.
The main activity has a variable to hold the surface view, if that variable hasn't been set before the info/instructions activity is called I get this error. I simply moved the surface view variable assignment into the main activity onCreate and all is well.
It is also possible that one uses a custom preference (e.g. custom dialog preference) that does not call "super.onSavedInstanceState()" which leads to the same error.