Android Studio Debugger : Stop when an variable gets a specific value - android

Scenario :
I have a variable and I want to find out where and when the variable gets for example the value 4. When this happens the debugger should stop at that line.
Is this possible with Android Studio ?

If I understand correctly what you're wanting to do is set what is called a "Watchpoint" in Android Studio, and here's a link to the IntelliJ documentation that discusses them:
https://www.jetbrains.com/help/idea/2016.3/creating-field-watchpoints.html
In particular, what you want to do is set a break-point on the member variable itself, right-click that break-point and set the watch on "field modification" and set a condition for when that variable becomes the specific value you're trying to find.
So, in this simple bit of code:
public class MainActivity extends AppCompatActivity
{
int mWatchMe = -10;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i=0 ; i<20 ; i++)
{
mWatchMe++;
}
}
}
You would set a break-point on the line: int mWatchMe = -10;.
Set the "Condition" and "modification" fields:
The execution should break where ever "mWatchMe" is set to '0':

This is possible. Right click on your breakpoint and then enter your expression "value == 4" in the condition field.

Related

Creating Object from other class

I have a settings screen where you can choose between, add and remove configurations for the app.
When adding a configuration, I create a new Instance of a inputBox Class (extending the settings activity class - where I stored the procedure for the standard android text input box) to query the name for the new configuration.
In the Onclick of this inputbox a procedure from the superClass (the settings-activity) is called to create a new configuration object.
This Procedure queries some things from the activity (e.g. selected spinner element) including the progress of a seekBar.
This is where I get a NPE:
java.lang.NullPointerException: Attempt to invoke virtual method'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
The same object creation procedure is also called on initialization of the app and works just fine.
I understand from the Error that the issue is that when calling the procedure from a child class the reference of the variables to the corrseponding elements of the screen is not set anymore - and therefore cannot be queried.
So the question:
How can I query values of activity elements, when the procedure is called from another class?
I know that the topic is quite broad, but I can't figure it out for a couple of days now
Thanks for your help in advance.
Here is a scheme of the problem:
public class Settings extends AppCompatActivity{
Context settingsContext = this;
private Spinner someSpinner;
//other elements
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
someSpinner = (Spinner) findViewById(R.id.someView);
//other elements
addNewConfig.setOnClickListener((v) --> {
inputBox inputBox = new inputBox("OK", "Cancel", settingsContext, "sourcePath",1,1);
newConfigName = inputBox.show();
});
public sSetting makeNewConfig(String name, String sourcePath, int dataFrom, int dataTo){
sSetting newConfig;
newConfig = new sSetting("NAME", someSpinner.getProgress()>0, ...);
return newConfig;
}
}
And the inputBox:
public final class inputBox extends Settings {
//someVars
inputBox(String buttonOk, String buttonCancel, Context setContext, String sourcePath, int dataFrom, int dataTo){
//variable setters
}
private String show() {
//show msgbox
//onclick ok
super.makeNewConfig(....);
}
For solving the problem I restructured my Project a little:
I removed the inputBox-Part, which, after some research considered for a too complicated solution for what I needed anyway.
However: I now added a editText to my Settings View.
Although I had to change my Settings view for this, it now looks better and it was ridiculously easy to edit the configuration name for the user.
I think in most cases that will do the trick. Adding Popup-Boxes just needs more error handling and makes the design more complicated
I hope this helps ;)
If you need the code for it it is available here:
GitHub - AIM

The "GenerateJavaStubs" task failed unexpectedly

I have created one new project in Visual studio and only che in .xml file (put two frame layouts) and when i debug the code i have one error, please told me the solution
Error 1 The "GenerateJavaStubs" task failed unexpectedly.
System.InvalidOperationException: Sequence contains no elements
at System.Linq.Enumerable.Max(IEnumerable`1 source)
at Xamarin.Android.Tools.TypeNameMapGenerator.WriteBinaryMapping(Stream o, Dictionary`2 mapping)
at Xamarin.Android.Tools.TypeNameMapGenerator.WriteJavaToManaged(Stream output)
at Xamarin.Android.Tasks.GenerateJavaStubs.UpdateWhenChanged(String path, Action`1 generator)
at Xamarin.Android.Tasks.GenerateJavaStubs.WriteTypeMappings(List`1 types)
at Xamarin.Android.Tasks.GenerateJavaStubs.Run()
at Xamarin.Android.Tasks.GenerateJavaStubs.Execute()
at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__20.MoveNext() TMS_TabletView.Droid
This still can happen if you use one of Xamarin Plugins that use CrossCurrentActivity, for example Plugins.Share and if you have Application class with [Application] tag. This is because on nuget installation it generates another Application class with same tag and that causes 'GenerateJavaStubs' failure.
Solution is simply delete one of Application classes / merge them into one.
For me this happened after installing the Xamarin Share Plugin (https://www.nuget.org/packages/Plugin.Share). I was setting the theme of my Android app in its assemblyinfo.cs with the line below:
[assembly: Application(Theme = "#style/AppStyle.myApp")]
Simply removing this line resolved the issue, and I then set the theme in MainActivity as you should really anyway.
I had the same issue and the error in detail was saying something like; "Path is too long. Bla bla name cannot exceed 248 characters and the other bla bla cannot exceed 260 characters".
And shortening the project name solved my issue.
If you have constructor in Activity class, please add default constructor.
Or you can remove constructors in class.
This is old source code.
[Activity(Label = "MyActivity", ScreenOrientation = ScreenOrientation.Portrait)]
public class MyActivity : BaseActivity
{
bool param;
protected override int LayoutResource
{
get
{
return Resource.Layout.myactivity;
}
}
public MyActivity(bool param = false)
{
this.param = param;
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
...
}
This is updated new source code.
[Activity(Label = "MyActivity", ScreenOrientation = ScreenOrientation.Portrait)]
public class MyActivity : BaseActivity
{
bool param;
protected override int LayoutResource
{
get
{
return Resource.Layout.myactivity;
}
}
public MyActivity()
{
}
public MyActivity(bool param = false)
{
this.param = param;
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
...
}
I experienced this problem, and got all the same error messages while creating my very first app on Visual Studio Professional 2015 (with Xamarin). No idea if this will be of any use to anyone else, but we stumbled on something that fixed the problem for us.
In MainActivity.cs, there is some default code when you first open up a "Blank App" project, but we had deleted some of this code, and copied/pasted over it. This is what it initially looks like:
namespace App3
{
[Activity(Label = "App3", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); };
}
}
}
To fix it: We tried putting back these lines into MainActivity.cs code:
[Activity(Label = "App3", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button>(Resource.Id.MyButton);
And then we ran the code and the error went away. Probably just a dumb mistake, and won't always solve the issue, but it worked for us.
I had this issue because for some reason my Android Class library got changed into an Android Application type - so VS was looking for Application class in the project.
Solution was to create a blank android class library, and compare project files.
I removed any xml tags from the broken project that were "application" specific.
like [<]AndroidApplication>true[<]/AndroidApplication>
I had this issue because i put activity events under #region block. after removing #region block, everything is working fine in my case.
I had this issue because of copying an Android Library to a new project.
Visual Studio automatically made me a new resource file, which resulted in having ambiguity problems between the resource file of project 1 and the file of project 2. After solving this, I didn't have a Java Stub error anymore. I don't know if this was the fix, but I didn't do anything else, so it almost has to be although it is a bit weird.
None of these answers ended up working for my issue. Here is what did work:
In your Solution Explorer, go to the Android project, right click -> Properties -> Android Options -> Linker -> Linking and choose Sdk Assemblies Only.
Also make sure in the Android project -> Properties -> Android Options -> Advanced properties -> Java Max Heap Size is set to 1G.
I was getting this error on doing a Release build
The "GenerateJavaStubs" task failed unexpectedly.
Nullreference Exception
Restarted VS cleared it up.

Android Passing Variable doesn't seem to click

I have created a random number and would like to pass it along to use in the same file just different class. Please help:
public void Start() {
int number = random.nextInt(3); // Gives a number such that 0 <= number < 2
then a few lines down I try to use number but it's telling me it's not a variable to use:
public void renderBackground(Canvas canvas) {
//TODO: you may wish to change background colors from here
if(number=="0") {
any kind of help is great appreciated!
The problem you are facing is because of the scope of variable number. I'm not sure you are using inner class or a separate class.
If it's a inner class, then declare the number at top of the first class like,
class Firstclass
{
public int number; // scope is public it can be accessed anywhere in class
method();
...
...
class Secondclass
{
method()
{
System.out.println("Your number is : " + number); // here you are accessing variable `number`
}
}
}
Also, try to change
if(number=="0") {
to
if(number==0) {
I think the problem is you are initializing 'number' inside a class, not the main class.
initialize number inside the main class then modify it in your method. ex:

Android application crashing when stepping into a method of a base class

I'm very new to Android programming and I am using Android Studio to target a Nexus 9. So far it's been a good/great experience.
I'm finally encountering some odd behavior though, when I tried something a little advanced -- sorry for the oddball question, I'd be happy with just some troubleshooting tips, since the observations don't give me much to go on. Here goes...
I have one class derived from another, as follows:
cWidget, which has method OnMyEvent()
cFrame extends cWidget, overrides OnMyEvent()
Each of my cWidgets (and hence my cFrames) has a linked list of "child" cWidgets (and/or cFrames), to form a tree structure. In both my cWidget.OnMyEvent() method and the cFrame.OnMyEvent() override I loop through the child cWidgets and call the OnMyEvent() on each -- so that my event is kind of "passed down" through the hierarchy by traversing the tree. My hope is that if the child is a cWidget it calls cWidget.OnMyEvent() and if it's actually a cFrame it calls the cFrame.OnMyEvent() override (this is how it would work in .NET, I should write some code to verify this is how it works here in Java but I realize now this is currently an assumption).
The problem: when I debug and set a breakpoint in cWidget.OnMyEvent() it never fires, even though there are definitely cWidgets in the tree. When I breakpoint on the call from cFrame.OnMyEvent() to a child cWidget.OnMyEvent(), and I inspect all the local variables, everything looks right; ie the child is a cWidget as expected, and nothing is null... but if I resume execution it still does not trip the breakpoint in the cWidget.OnMyEvent() as expected, it just passes over it. Even weirder, if I "Step Into" the call to cWidget.OnMyEvent(), my application halts with an "Unfortunately, MyFirstApp has stopped", and no exception report in my logcat.
So... very sorry for the long description but I'm not sure what's important and what's not. Without an exception report I'm not sure how to treat this problem, and there is some chance I am breaking some rules by linking together parents and children in the same tree and hoping Java knows whether to call the base method or the override. (This worked in .NET, and so far everything there has worked here but maybe not in this case.)
Thanks a lot for any thoughts or troubleshooting tips.
EDIT: I boiled it down and tested it, get similar results but still don't know why. I defined cA with an AddChild and Handle method, then derived cB and overrode Handle. I created a tree (two cAs as children of a cB) and then called cB handle. When I try to build a tree and call Handle it crashes. I'm guessing I'm trying a .NET trick that is disallowed here.
// *************
// BASE CLASS WITH AddChild, Handle
// *************
public class cA
{
public int m_Tag = 0;
protected cA ptr_FirstChild = null;
protected cA ptr_LastChild = null;
protected cA ptr_Parent = null;
protected cA ptr_NextSibling = null;
public cA(int tag)
{
m_Tag = tag;
}
public void AddChild(cA a)
{
a.ptr_Parent = this;
if (ptr_FirstChild == null)
{
ptr_FirstChild = a;
ptr_LastChild = a;
}
else
{
ptr_LastChild.ptr_NextSibling = a;
ptr_LastChild = a;
}
}
public void Handle()
{
int a;
a=3;
cA tmp = ptr_FirstChild;
while (tmp!= null)
{
tmp.Handle();
tmp = tmp.ptr_NextSibling;
}
}
}
// *************
// DERIVED CLASS, overrides Handle
// *************
public class cB extends cA
{
public cB(int tag)
{
super(tag);
}
#Override
public void Handle()
{
int a;
a=4;
cA tmp = ptr_FirstChild;
while (tmp!= null)
{
tmp.Handle();
tmp = tmp.ptr_NextSibling;
}
}
}
// *************
// Usage of classes
// build a tree with both cAs and cBs, then call
// root.Handle, hoping to traverse the tree.
// *************
public cA ptr_Root; // define the 'root' of the tree
cA a1 = new cA(1); // instantiate all leaves
cA a2 = new cA(2);
cB b1 = new cB(1);
ptr_Root = b1; // build the tree
b1.AddChild(a1);
b1.AddChild(a2);
b1.Handle(); // call Handle on the root, intending to traverse the tree, but this halts the program

Screen Rotation with Threading using Mono Android?

In CommonsWare eBook Android v3.6 pg 270, he discusses handling threads with rotation. He offers a solution where you create an inner static class to hold your state, call detach in the workflow and then attach again during screen rotation.
The problem is that each rotation will destroy the Activity and recreate it in Android, thus when you come back your thread may reference the destroyed activity giving you an exception for accessing an object set for collection.
I tried this in Mono Android and was unable to get it to work, I got an exception every single time. My question, hopefully Jonathan Pryer reads this is, how can I make this work in Mono Android? I have asked this twice on the forums with no results. So I am taking it to StackOverflow. I wanted to post the actualy code but I didn't want to violate CommonsWare licensing. So please take a look at the example in the book.
What was the exception? What's the adb logcat output?
The C# equivalent is the-same-but-different from the Java source. For example, here's the "rotation-aware" version of the default Mono for Android sample project:
[Activity (Label = "Scratch.PreserveCount", MainLauncher = true)]
public class Activity1 : Activity
{
CountInfo Info;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button> (Resource.Id.myButton);
button.Click += delegate {
SetButtonCount (button, Info.Count++);
};
Info = (CountInfo) LastNonConfigurationInstance;
if (Info == null) {
Info = new CountInfo {
Count = 1,
};
} else {
SetButtonCount (button, Info.Count);
}
}
void SetButtonCount (Button button, int count)
{
button.Text = string.Format ("{0} clicks!", Info.Count);
}
public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
return Info;
}
class CountInfo : Java.Lang.Object {
public int Count;
}
}
It's the same basic approach as the Java sample: the Activity.OnRetainNonConfigurationInstance() method is invoked by Android before the Activity is disposed, so we return our "state" from that method. The Activity.LastNonConfigurationInstance property will return null the first time it's invoked, otherwise it will return the last value returned from OnRetainNonConfigurationInstance(). The only missing piece of the puzzle is that the "state" object (CountInfo here) must inherit from Java.Lang.Object as we're passing the instance to Java.

Categories

Resources