Windows Phone 8 Equivalent for Android's StartActivityForResult - android

I am from an Android background and am progressing into Windows Phone 8.
I have a Page that uses the camera to decode a QR code and this works fine. In Android I would start this Activity using the Intent StartActivityForResult, which would then give me the decoded value back to the original Activity.
I have searched but could not find an obvious equivalent in Windows Phone 8. My thought at the moment is to navigate to the calling page with a query string containing the decoded value and alter the back stack, but this seems a little messy.
The Question
Is there an equivalent to the process in android, and if so can someone outline the methodology so I may see it in action?

First, there's no such thing in WP8, so you'll need a workaround. Workarounds could be different, and the linked question (and answer) is one of the potential approaches. I personally do this a bit differently. I'll describe my current project's architecture here, though it may not be applicable to your situation, since my app is quite big and has a complex structure. But I'll try to explain how it could be applied to your situation.
Particularly, my current app consists of so called services (just my name, not a standard one). Those have different scope (some are used by 1 page, some are global for the app), different lifetime, and so on. Essentially, every service is a class implementing a well-defined interface, so that other services could use that.
Next, services could depend on each other. I'm using Ninject framework for dependency injection. Essentially, if service A depends on service B, it leads to a code like this:
public class B : IB
{
...
}
public class A
{
IB b;
public A(IB b)
{
this.b = b;
}
}
where IB is an interface, which service B implements.
Then I have view models (yes, I'm using MVVM and you probably should too, if you want to build a reasonably big WP8 app). View models are using services to perform app functions. Some of the services are used by several view models. For example, I have one service that fetches some data from the web, and keep it up to date with periodic polling. That web data is used in several pages of the application, so it should be shared between different view models. It is achieved by dependency injection again, so that all interested view models accept this service instance as a constructor parameter.
public class MainPageViewModel : INotifyPropertChanged
{
private string webData;
public MainPageViewModel(IWebDataService service)
{
webData = service.CurrentWebData;
service.WebDataChanged += (o, e) => webData = service.CurrentWebData;
}
...
}
public class DetailPageViewModel : INotifyPropertChanged
{
private string webData;
public DetailPageViewModel(IWebDataService service)
{
webData = service.CurrentWebData;
service.WebDataChanged += (o, e) => webData = service.CurrentWebData;
}
...
}
public class WebDataService : IWebDataService
{
public string CurrentWebData;
public event EventHandler WebDataUpdated;
...
}
Ninject allows me to have a single instance of IWebDataService instantiated, so that main and details page share the same instance of it. When the web data is updated, an event is fired, so that both view models can update their instances of web data, and push this new data to the views.
So here's how I do it. You could potentially reuse some part of this architecture, like having a singleton instance of some class accessible by different pages. One page puts some new data to that singleton instance, and, when data is updated (event fired or during construction, if garbage collector had enough time to kill existing page and/or view model instance), another page reads the updated data. That's how they share.
If you want me to go deeper into details on some topic, please feel free to ask in comments. Android developers are more than welcomed to the Windows Phone. :)

Related

Android: persisting data across app lifecycle

I'm working on an Android app that uses some background tasks (AsyncTasks) and I want to use best practices regarding data persistence across app lifecycle and tasks callbacks.
Up to now, I have a mix of practices regarding this:
1) I have some static fields in classes where AsyncTasks are used in the form of:
private static String str1;
private static String str2;
private static int int1;
...//=>no more than 6 static fields
2) I use a sinleton App instance with many getters/setters in the form of:
package xxx.xxx.xxx
import xxx.xxx.xxx
...
public class AppSettings {
private static AppSettings singleton;
private String _field1;
...//=>many fields
public void setField1(String field1) { _field1 = field1; }
public String getField1() { return _field1; }
...//=>many getters/setters
private AppSettings() {}
public AppSettings getInstance(){
if (instance== null) {
synchronized(AppSettings.class) {
if (instance == null)
instance = new AppSettings();
}
}
return instance;
}
}
I definitely know that abusing of static fields is not good at all, so I decided to replace them all, but I'm not completely sure if my second approach -having an application instance in a singleton with many getters/setters- is considered a good way to go, and in case not, I would like to know about better alternatives.
Thank you very much.
Edit 1: Just to clarify.
In order for you to understand more clearly what I use my AppSettings singleton class for I'll give you two examples:
1) I use it to store app setting/configuration values (that's why the name) to be available anywhere. For example, font color, font size, whatever.
2) I use it to store temporary data/values. For example, my main activity creates a small video in the backgroung using "VideoHelper" class and called through an AsyncTask, and as video generation process needs some parameters from main activity, I use AppSettings getters/setters to send them through.
Edit 2: Better explanation of everything.
Thanks to #a_local_nobody I realized my "case of use" was not so clear so I'll add a few things more.
My AppSettings is not being used to store user settings, I use SharedPreferences for that, but instead app default configuration parameters.
To give an example, I store activities background color (and this is just an example) so if in the future I change my mind and decide to use another background color this setting (and many more) are centralized there. It's like a "container" for many default app settings.
Regarding the use of getters and setters in this app singleton class, I think I'll foloww #a_local_nobody suggestion related to define some static variables in each class and use them as needed instead of having a bunch of unrelated getters/setters globally.
Anyway, all comments are welcome.
Well, you are talking about persisting data across app lifecycle which, in my mind, sounds like you're looking for a ViewModel:
The ViewModel class is designed to store and manage UI-related data in
a lifecycle conscious way. The ViewModel class allows data to survive
configuration changes such as screen rotations.
as well as:
The purpose of the ViewModel is to acquire and keep the information
that is necessary for an Activity or a Fragment. The Activity or the
Fragment should be able to observe changes in the ViewModel.
ViewModels form part of the MVVM design pattern, with loads of examples available online.
For more info, have a look at the documentation
on a side-note, perhaps you can have a look at the google sunflower project for some ideas on how to implement the new architecture components, which includes usages of ViewModels.
Also worth adding, is that what you've created with your AppSettings solution, is a big dependency. Various things will depend on this single object and it will be needed throughout your application, most likely. You might consider, instead of creating it like this, to rather use dependency injection with your options, for android, probably being either Dagger 2 or Koin for kotlin (if you ever swap over to kotlin) or perhaps your own form of dependency injection without having to use these frameworks.
Hope this helps
Edit based on feedback from OP:
I use it to store app setting/configuration values (that's why the
name) to be available anywhere. For example, font color, font size,
whatever.
this sounds like a better use case for Shared preferences, especially if these are settings defined by a user, otherwise you should be savings these into strings.xml etc. and making use of localization
I use it to store temporary data/values. For example, my main activity
creates a small video in the background using "VideoHelper" class and
called through an AsyncTask, and as video generation process needs
some parameters from main activity, I use AppSettings getters/setters
to send them through.
if you have a VideoHelper class, you might be better off either creating a Builder design pattern for this object, or having static variables for this helper to change its functionality as you need to, if these are variables for your VideoHelper, then they should be located with your VideoHelper.
Things which change together should usually stay together.
Your approach doesn't qualify as "best practices" in modern android development.
The recommended way of handling configuration changes is by using the new architecture component: ViewModel
It have the property of surviving the onDestroy triggered when a configuration change occurs.
Basically, you will need to move this AppSettings code to a ViewModel.

Unit testing realistic Android classes. Test environment, the lifecycle, and responses

There seems to be no end to the number of posts discussing how to unit test completely unrealistic things.
An abundance of tutorials, videos etc outline what unit tests are and how you do them. There do not however seem to be many (if any) resources which outline how to test something real.
After all.. in reality the 'units' that we are testing are generally significantly more complex than a method taking inputs and giving an output.
I am working with Android at the moment and was investigating how to unit test my application.
My application is essentially made up of views and server requests. You click button x and it changes the view displayed. You click button y and it loads data from the server and populates a list.
Below is some source code. I have essentially pieced together an example setup which demonstrates the things that are confusing (to me). The things that I find conceptually difficult to unit test.
public class ChainActivity extends FragmentActivity {
private PRFragmentTabHost mTabHost;
public GetChainResponse.Data responseData;
Integer chainId; //ref to chain we are getting - passed in
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Get the chain id we are getting
Bundle extras = getIntent().getExtras();
chainId = extras.getInt("chainId");
setContentView(R.layout.activity_base);
//Set up the tabs
mTabHost = (PRFragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
mTabHost.addTab(mTabHost.newTabSpec("Details").setIndicator("Details", null), ChainDetailsFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Pictures").setIndicator("Pictures", null), PicturesFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("Cats").setIndicator("Cats", null), CatsFragment.class, null);
}
#Override
public void onStart() {
super.onStart();
//Initiate the data load
loadChainData();
}
//Method loads the chain data
public void loadChainData(){
PRAPIInterface apiService = ApiService.getInstance();
Integer limit = 4;
apiService.getChain(chainId, limit, new Callback<GetChainResponse>() {
#Override
public void success(GetChainResponse pr, Response response) {
lastData = System.nanoTime();
//Save the response data
responseData = pr.data;
//Get the current tab and pass the loaded data to it
String currentTabTag = mTabHost.getCurrentTabTag();
DataLoadedInterface currentTab = (DataLoadedInterface) getSupportFragmentManager().findFragmentByTag(currentTabTag);
currentTab.dataLoaded(responseData, false);
}
#Override
public void failure(RetrofitError retrofitError) {
// Log error here since request failed
Log.w("Failed", "Failed" + retrofitError.getUrl());
Log.w("Failed", "Failed" + retrofitError.getBody());
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Fragment fragment = getSupportFragmentManager().findFragmentByTag(mTabHost.getCurrentTabTag());
if (fragment != null) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
}
So.. I am aware of Roboeletric, Robotium etc and other libraries that are available for testing on Android. I am however looking for conceptual advice.
Android provides ActivityUnitTestCase
I can subclass this and setup a test for my activity.
Part 1
In principle I could test my onCreate by verifying that mTabHost is not null BUT I don't want to make it publicly available, nor do I want to have a getter to its value.
I figured that I could test the existence of my fragments but i can in fact not. Because the activity runs in 'isolation' it seemingly does not actually create the fragments for the tabs.
Part 2
Next is onStart. This calls another method. It has no return value. I cant test a response.
It is however important that i test that onStart we load our initial data..
Within loadChainData I could set a Boolean indicating that I am loading data and verify this but a coworker could just set this Boolean to true by default and my test would pass.
Furthermore I don't want to test loadChainData 'again'.. I will be testing this method anyway. One idea that springs to mind is stubbing out loadChainData and verifying that it is called and leaving it at that. This however seems to be difficult to do with Android (anyone..?) and does not really fit with the sentiment that testing should be fun.
Part 3
loadChainData loads some data from the server using retrofit. Because in reality this method executes asynchronously there is again no response from this method. I have found an appropriate way of returning mock data by swapping out the retrofit client but doing this swapping is not apparently simple.
At the moment I use a singleton for my ApiService. I want to essentially replace what is built the first time this singleton is called. There are potential complex solutions for this like using a Dependency injection library (like Dagger) but given what I want to achieve I feel that there should be a much simpler way of doing this.
My initial thoughts are that if the application could be instantiated with say a test flag. The singleton would return the test client. Alternatively it would default to the real client. This in my mind smells a little.. could someone explain what the smell is, and how one could appropriately resolve it?
Even if the above was considered a fair suggestion there seems to be no easy way to actually do it with ActivityUnitTestCase.
Part 4
Finally is onActivityResult.
Again, there is no response.
This time the method in question interacts with other units elsewhere. Units that act differently within the constraints of ActivityUnitTestCase anyway.
I could wrap my manipulation of the support fragment manager, mock my wrapper, return a mocked fragment, verify that its onActivityResult method is called.. but again this seems incredibly tough to do. Furthermore this adds complexity to my code to allow something to be testable. I have no interest in increasing complexity just to test..
So..
Does anyone with real experience unit testing on mobile have any insight on how to appropriately tests a class such as this one. As you can see it is not really a case of 'put 2 in, does 4 come out' :)
A lot of resources mention how testing is underdone. This is why :) Any advice would be greatly appreciated.
T
onCreate
I would test in two ways, one using some form of AndroidTestCase this would allow the testing of extras you send in the Bundle.
( I would add error handling to throw an error if the extra is not present )
( I would change loadChainData() to take chainId as a paramater )
To test your tabs are instantiated correct I would use espresso for an Acceptance test to validate your views are present.
onStart
There is no Dependency Inversion here and so you cannot test the service methods are called. You would want to test getChain is called. What happens when you create that service, could you do it in the constructor?
( I would move away from the Activity here and encapsulate all behaviour from onStart in some other class [perhaps MVC could help] that way you aren't constrained by the lifecycle.
( I would also add another layer of callback's on top of Volley in to the Activity, that way you can test your listeners return the correct success or failure, but you don't have to worry about the tabs [the activity ui]).
If you really wanted to test asynchronisity (which I wouldn't advise) you can use Espresso and that can help you manage the test to still get callbacks see custom resource idoling.
onActivityResult
I believe using Robolectric you could pass it a Mockito mock fragment manager in order to return you a stub fragment and validate the behviour of the the fragment tab host, then you would call onActivityResult yourself: whether testing this actually gives you any benefit is another question.
Overall testing lifecycle methods is like testing anything else, for it to be testable you need to abstract away any ideas of threading, you need to be in control of your dependencies and I find the closer you adhere to SOLID the easier testing is. In the wake of these stumbling blocks, this is why Robolectric, InstrumentationTests and Espresso where created.
In summary sorry, there is no straight forward answer here, you have to ask yourself - do I get any benefit from testing these things, am I testing my code or am I testing the framework, what is the cost benefit of testing this Activity does it actually encumber future changes rather than gain me confidence.

android - Headless Retained Fragment vs. Class with public static variables (Global Class)

I'm part of an Android project that uses a global class that contains public static variables, like the example below:
public class Globals {
public static MyObject variable = "this is a test";
}
In the middle of using the application, this global variable's value will be changed let's say:
#Override
public void onCreate(Bundle savedInstanceState) {
Globals.variable = new MyObject(somethingHere);
}
And I came across using Headless Retained Fragments from these blog posts:
http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html
http://www.vogella.com/tutorials/AndroidFragments/article.html#headlessfragments
Problem:
I need to have a reference of an initialized object all over the application.
Question:
which is better to implement, a good practice, and practical? Or is there another way I could store a reference of an object all over the application?
The global class has been used over the project, and works fine, but are there any downsides of this implementation?
are there any downsides of this implementation?
Memory leaks, depending on what you are storing there. Leaks are why static data members are considered poor form in classic Java, even if we tend to use them more in Android app development.
Also, this data needs to be considered a cache, one that has to be able to be lazy-created on first access. Your process can be terminated at any point (wiping out the static data member) and the user can return to any activity in your app (courtesy of the recent-tasks list). If you want this data to survive process termination, the most likely solution will be to persist it in a file, database, or SharedPreferences.
All that being said, a retained fragment is a per-activity solution, not a per-application solution, and so it is not a valid alternative for your scenario AFAICT.

How do I share common functions and data across many activities in a single android application

I am looking for how to share functions and data across multiple activities within a single application. I researched the daylights out of it and find some ideology war between overriding the extend for the application and doing a singleton, neither of which I can find examples sufficient to make me understand. Basically I want to share data and share functions. All activities need the same functions and data so this is not one activity sharing data with another activity. It is all activities needing to have access to the same functions and data.
What I want to know is what is the way to go and how do I do it. I need to see what I need to do in my 34 activities, what the class that is going to be common looks like, and what the Manifest entry needs to be. I also need to be sure the common data area will not be closed by the OS.
This is my first Android - Java program and now find my 15,000 line, 34 activity application needs some structure. I know, should have done things differently but the app works really well with two exceptions. One is that it is structurally a mess. Two is that the fact it is a mess is making it hard to fix one behavior I would like to fix.
This is a GPS based application for racing sailboats. It is timing critical and every activity basically runs a once a second loop inside the location manager onLocationChanged function. That part is fine and I do not want to put the GPS code in one place. The problem is that most activities need to filter the data so a lot of code is copied and pasted to the activities. The filter needs history so it needs to remember a state. There are other functions that are used by several activities so these have been copied as well. Think of a function that averages the last three GPS speed readings. It needs to save some history, do its thing, and give a result. All activities need to do the exact same thing. All this works but the problem is that the averaging starts over every time I switch activities because every activity has its own filter. That gives a glitch in the data that I need to get rid of. I need common place to save the data and hopefully a common place to run the filtering and other functions that are common. If every activity can call the filter function that is using common state data, there will be no glitch across activity changes.
I would appreciate some guidance.
Why you don't just make a Class with only static functions, passing needed Parameters? An example if you want to show an ErrorDialog
public class SharedHelper{
public static Dialog showErrorDialog(Context ctx, String message, String title, DialogInterface.OnClickListener okListener, DialogInterface.OnClickListener cancelListener){
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setMessage(message).setTitle(tilte);
if (okListener != null){
builder.setPositiveButton(R.string.button_positive, okListener);
}
if (cancelListener != null){
builder.setNegativeButton(R.string.button_negative, cancelListener);
}
return builder.show();
}
}
Singletons are (from my point of view) one of the uglyest design pattern and will bite you sooner or later. Putting anything in Application requires you to cast it everytime to the Special Application class you designed. A class with only statics however is very flexible in its usage and doesn't need an instance to work.
For the storage-issue:
lookup "SharedPreferences" & "SQLite" and decide afterwards which storage-type suits your needs more.
For the methods-issue:
This question is a bit more complex and there are different ways to do it. For example you could write a parent-class that implements all your globally needed questions and you let all your activity-classes inherit from it.
public class MyParentActivity extends Activity {
public void myMethod() {
}
}
and:
public class Activity1of34 extends MyParentActivity {
myMethod();
}
I think what this comes down to is not an Android problem but an Object-Oriented Programming problem. If I understand the situation correctly, I'm betting the best solution would be to take your shared filter and create a new Filter class that is instantiated within each Activity (this is likely more manageable than a singleton, but not having seen your use case, it's hard to say for sure). If you need to centrally track the averaging, you can simply create a static variable within the Filter class that maintains the same value during the life of the application. If you really want to maintain that average (even past the application's current lifecycle), you can persist it in a database or other local data options. However, I don't see any reason to put everything in a singleton just to maintain that average. Singletons (and all static data structures) can be potentially troublesome if used incorrectly.
I, for one, do not mind the singleton pattern. Of course as everything else it should not be abused.
This is the construction I use for my shared objects. My app is divided into modules this way but can just as well be used in your case.
public class SharedDataObject {
private Context context;
private static SharedDataObject instance;
public static SharedDataObject getInstance() {
if (instance == null) throw new RuntimeException("Reference to SharedDataObject was null");
return instance;
}
public static SharedDataObject createInstance(Context context) {
if (instance != null) {
return instance;
}
return instance = new SharedDataObject(context.getApplicationContext());
}
// notice the constructor is private
private SharedDataObject(Context context) {
this.context = context;
}
...
public void myMethod() {
// do stuff
}
}
Notice that it uses the application context, that means among other things, means that the context owned by SharedDataObject cannot be used for GUI operations. But, the context will live for the entire lifetime of the application, which is nice.
Furthermore I hate having to pass a context everytime I wish to call methods on my SharedDataObject, thus I have a splashscreen calling SharedDataObject.createInstance() on all my modules.
Once an instance is create, I can call:
SharedDataObject.getInstance().myMethod();
Anywhere in my code, regardless of a context being present or not (from the place calling this code that is).

Efficiently Passing Custom Object Data between Android Activities [Mono Android]

I've been stumped with this for a while now.
I'm working on an android app that stores a person's fish catches, favorite fishing locations, tackle box inventory and other data. All my classes are Serializable and can saved and loaded between activities which seems to work thus far. But I'm predicting as more and more data is stored, the app will start running slow.
What I'm basically asking is there any way to retain this data throughout the entire application, so I don't have to load it every time a new screen pops up. I've already found the following information to help but it needs to be a little more clear for me to understand:
Another forum said you could stuff it in the Application object:
[Application]
public class MyApp : Android.App.Application {
public MyApp(IntPtr handle)
: base (handle)
{
}
public FishingData Data {get; set;}
}
Then within your Activity:
((MyApp) this.ApplicationContext).Data = value;
So I've never really heard of doing this approach before and I'm not sure this will live through the entire application process (I feel like either way it's going to have to load the data via serialization. Here's what I want the app todo:
The first activity is the main menu and the following must be done when the screen loads:
If a settings file is found, use serialization to load a previous FishingData object (I know how to do this)
If not, then create a new clean FishingData object to save later (I know this as well)
So now that we have a FishingData object, how do I ensure that I don't have to repeat steps 1-2 in every activity. How can I somehow pass the FishingData object to the next activity and ensure that it lives globaly while the app is still living. I only want to load it once (via serializing) (<--Don't know how to do this) and save it only when a user adds data to this object (which I know how to do).
Any help will be appreciated. This is bugging me I cant seem to figure this out. This seems like it would be a common thing to do but I haven't had any luck finding any detailed information.
Here is how I would pass my data around the app via parcelable. Lets say you have a class named Fisherman (for a user basically)
public class Fisherman implements Parcelable {
private String name;
private Tacklebox box;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(name);
out.writeParcelable(box, 0);
}
public static final Parcelable.Creator<Fisherman> CREATOR
= new Parcelable.Creator<Fisherman>() {
public Fisherman createFromParcel(Parcel in) {
return new Fisherman(in);
}
public Fisherman[] newArray(int size) {
return new Fisherman[size];
}
};
private Fisherman(Parcel in) {
name = in.readString();
box = in.readParcelable(com.fisher.Tacklebox);
}
}
In this example, you define parcelable for each data model you have. So say you have a fisherman object, that contains another object called tacklebox. You will also define this for tacklebox, and so on if you continue to nest models. This way, all you need to do to pass data between activities is
Intent intent = new Intent(this, Activity.class);
intent.putParcelableExtra("com.fisher.Fisherman", fisherman);
and read
Bundle b = getIntent().getExtras();
Fisherman fisher = b.getParcelable("com.fisher.Fisherman");
This unfortunetly answers only step 3 of your problem, but I suggest breaking each one of your 3 steps into its own question because what your trying to do is slightly more lengthy than one question
You can use this approach, it will live as long as your Application object is alive (Which means it will live through your entire application and activities). You can read more about using global variables stored in the Application object here. I don't think mono would make a difference which will prevent you from using this approach.

Categories

Resources