I am bigginner in android and want to ask. Is there a way to access elements of an array that is declared as public static in different other activities under same package?
You can use intent on accessing value from another class
Class1:
Intent intent = new Intent(this, ClassB);
String[] data = new String[] {"value1", "value2"};
intent.putExtra("strings", data);
startActivity(intent);
Class2:
public void onCreate() {
Intent intent = getIntent();
String[] data = intent.getStringArrayExtra("strings");
}
Related
I am trying to store an Int32[] Array and bool[] Array to Firebase but it isn't working for me. I have searched on various places, but couldn't find a solution. Can anyone tell me, how one can store an array to Firebase Real-time DB from Unity.
I am using System.Reflection to get all the public static fields of the class UserPrefs.
Here is the code, I am trying to do this job...
System.Type type = typeof(UserPrefs);
FieldInfo[] fields = type.GetFields();
foreach (var field in fields) {
if (user != null)
dbReference.Child("users").Child(user.UserId).Child(field.Name).SetValueAsync(field.GetValue(null));
else
Debug.LogError("There is no user LoggedIn to write...");
}
Above code saves all values other than arrays. Error given on arrays is following:
InvalidCastException: Cannot cast from source type to destination
type.
Firebase.Database.Internal.Utilities.Validation.ValidateWritableObject
(System.Object object)
Any help will be much appreciated...
You need a class like this.
public class MyClass
{
public int[] intArray = new int[10];
}
Then you can write that object to the Firebase like this.
public void WriteArrays()
{
MyClass temp = new MyClass();
for (int i = 0; i < temp.intArray.Length; i++)
{
temp.intArray[i] = i;
}
databaseReference.Child("MyArrayNode").SetRawJsonValueAsync(JsonUtility.ToJson(temp));
}
databaseReference is a reference to your root.
Same way you can do this for your bool[] also.
For a more general solution you can copy the JsonHelper class which was suggested here.
Example usage:
string jsonArray = JsonHelper.ToJsonArray(mySerializeableList);
var nodeToUpdate = this.dbReference.Child("wantedNode");
nodeToUpdate.SetRawJsonValueAsync(jsonArray);
This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 5 years ago.
While I could serialize/deserialize simple data with JsonUtility, when trying to load an array of objects into my game, Unity didn't respond well.
I do understand that the utility doesn't take arrays, so alternative solutions are needed.
I've tried using the wrapper posted here (Thanks!!), but it's still not doing what I'd expect it to do.
While I'm passing all the details into the JSON, when saving it, it's only saving instanceIDs, which are not very useful for persistency.
Here's the step by step.
1. Creating the object
private Customer[] _customerDeck;
Customer yidler = new GameObject().AddComponent<Customer>();
yidler.race = GameController.Race.Alien;
yidler.initial = true;
yidler.patience = 3;
yidler.dice = new ResourceGroup();
yidler.dice.diceRequired = 1;
yidler.dice.resources = new Dictionary<GameController.Resource, int>();
yidler.dice.resources.Add(GameController.Resource.Food, 3);
yidler.dice.resources.Add(GameController.Resource.Beverage, 0);
yidler.dice.resources.Add(GameController.Resource.Dessert, 1);
yidler.moneyAwarded = 6;
yidler.fidelityAwarded = 1;
yidler.starsAwarded = 0;
yidler.initial = true;
_customerDeck[0] = yidler;
JSONManager.SaveCustomers(_customerDeck);
2. Saving the JSON
public static void SaveCustomers(Customer[] customers)
{
string filePath = Path.Combine(Application.streamingAssetsPath, customerCardsFile);
if(File.Exists(filePath))
{
string data = JsonHelper.ToJson<Customer>(customers);
File.WriteAllText(filePath, data);
}
else
{
Supporting.Log("Cannot find Customers JSON", 1);
}
}
public static class JsonHelper
{
public static T[] FromJson<T>(string json)
{
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
return wrapper.Items;
}
public static string ToJson<T>(T[] array)
{
Wrapper<T> wrapper = new Wrapper<T>();
wrapper.Items = array;
return JsonUtility.ToJson(wrapper);
}
[System.Serializable]
private class Wrapper<T>
{
public T[] Items;
}
}
3. Additional Info
The Customer class is System.Serializable, same as the ResourceGroup referenced within it.
This is the resulting json
{"Items":[{"instanceID":-47734},{"instanceID":0},{"instanceID":0},{"instanceID":0},{"instanceID":0}]}
First of all try remove MonoBehaviour inheritance from Customer class. Also Unity's default serializer doesn't support Dictionary<> serialization. Try to change from Dictionary to a List of Serializable class. Also check that all inner Customer data fields are serializable too.
I am new in hadoop and mapreduce programming and don't know what should i do. I want to define an array of int in hadoop partitioner. i want to feel in this array in main function and use its content in partitioner. I have tried to use IntWritable and array of it but none of them didn't work . I tried to use IntArrayWritable but again it didn't work. I will be pleased if some one help me. Thank you so much
public static IntWritable h = new IntWritable[1];
public static void main(String[] args) throws Exception {
h[0] = new IntWritable(1);
}
public static class CaderPartitioner extends Partitioner <Text,IntWritable> {
#Override
public int getPartition(Text key, IntWritable value, int numReduceTasks) {
return h[0].get();
}
}
if you have limited number of values, you can do in the below way.
set the values on the configuration object like below in main method.
Configuration conf = new Configuration();
conf.setInt("key1", value1);
conf.setInt("key2", value2);
Then implement the Configurable interface for your Partitioner class and get the configuration object, then key/values from it inside your Partitioner
public class testPartitioner extends Partitioner<Text, IntWritable> implements Configurable{
Configuration config = null;
#Override
public int getPartition(Text arg0, IntWritable arg1, int arg2) {
//get your values based on the keys in the partitioner
int value = getConf().getInt("key");
//do stuff on value
return 0;
}
#Override
public Configuration getConf() {
// TODO Auto-generated method stub
return this.config;
}
#Override
public void setConf(Configuration configuration) {
this.config = configuration;
}
}
supporting link
https://cornercases.wordpress.com/2011/05/06/an-example-configurable-partitioner/
note if you have huge number of values in a file then better to find a way to get cache files from job object in Partitioner
Here's a refactored version of the partitioner. The main changes are:
Removed the main() which isnt needed, initialization should be done in the constructor
Removed static from the class and member variables
public class CaderPartitioner extends Partitioner<Text,IntWritable> {
private IntWritable[] h;
public CaderPartitioner() {
h = new IntWritable[1];
h[0] = new IntWritable(1);
}
#Override
public int getPartition(Text key, IntWritable value, int numReduceTasks) {
return h[0].get();
}
}
Notes:
h doesn't need to be a Writable, unless you have additional logic not included in the question.
It isn't clear what the h[] is for, are you going to configure it? In which case the partitioner will probably need to implement Configurable so you can use a Configurable object to set the array up in some way.
I need to deserialize the next Json string that has several nested Json arrays:
{"d1":[["11791452",[["980",""]]],["11791453",[["1060",""],["1140",""],["1220",""],["1300",""]]],["11791454",[["1070",""]]]]}
I try to do it in several steps, so far I'm able to deserialize three levels of nested arrays. As follow:
{"aOaOa":[[["1060",""],["1140",""],["1220",""],["1300",""]]]}
public class ThreeSimpleNestedArrays
{
public List<List<string[]>> aOaOa; //array of arrays of arrays
public ThreeSimpleNestedArrays()
{
aOaOa = new List<List<string[]>>();
}
}
But the problem arise when I add the extra string in the array structure:
{"TEST": [["11791453",[["1060",""],["1140",""],["1220",""],["1300",""]]],["123456",[["0","1"],["2","3"]]]]}
public class ComplexNestedArray
{
public List<Dictionary<string,List<string[]> >> TEST;
public ComplexNestedArray()
{
TEST = new List<Dictionary<string, List<string[]>>>();
}
}
I'm getting the next error message:
"Unable to cast object of type 'System.String' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'."
What am I missing?
Can anybody suggest a way to deserialize an object like this nested within Json arrays using DataContractJsonSerializer?
The code I use to deserialize is the next:
//Works
DataContractJsonSerializer dcJsonSer = new DataContractJsonSerializer(typeof(ThreeSimpleNestedArrays));
ThreeSimpleNestedArrays root = (ThreeSimpleNestedArrays)dcJsonSer.ReadObject(str);
//Don't work
DataContractJsonSerializer dcJsonSer = new DataContractJsonSerializer(typeof(ComplexNestedArray));
ComplexNestedArray root = (ComplexNestedArray)dcJsonSer.ReadObject(str);
Btw, I'm able to deserilize the object when it is serilized as a Json Object as follow:
{"TEST": [{"s": "11791453","aOa": [["1060",""],["1140",""],["1220",""],["1300",""]]},{"s": "123456","aOa":[["0","1"],["2","3"]]}]}
using a class with two members (a string "s" and a List of string[] "aOa"), but without the names, when the object is serialized as an array, I'm unable to do it.
Any suggestion?
Ok, it looks like the DataContractJsonSerializer is smarter than I though .
It turns out that the way to deserialize that kid of nested objects array is with a class like this:
public class ComplexNestedArray
{
//{"TEST": [["11791453",[["1060",""],["1140",""],["1220",""],["1300",""]]],["123456",[["0","1"],["2","3"]]]]}
public List<List<object>> TEST { get; set; }
}
After that, it is only a mater to do a couple of for cycles and casts to the appropriate class structure.
Btw, This is a MUST in your toolbox in case you have to deal with Json:
json2csharp
Here is my solution. However I'll try to add later a way for your full json:
class Program {
static void Main(string[] args) {
new Program();
}
public Program() {
string full = "{\"d1\":[[\"11791452\",[[\"980\",\"\"]]],[\"11791453\",[[\"1060\",\"\"],[\"1140\",\"\"],[\"1220\",\"\"],[\"1300\",\"\"]]],[\"11791454\",[[\"1070\",\"\"]]]]}";
string simple1 = "{\"aOa\":[[\"1060\",\"\"],[\"1140\",\"\"],[\"1220\",\"\"],[\"1300\",\"\"]]}";
string simple2 = "{\"aOaOa\":[[[\"1060\",\"\"],[\"1140\",\"\"],[\"1220\",\"\"],[\"1300\",\"\"]]]}";
DataContractJsonSerializer d1 = new DataContractJsonSerializer(typeof(S1));
S1 r1 = (S1)d1.ReadObject(new MemoryStream(Encoding.Default.GetBytes(simple1)));
DataContractJsonSerializer d2 = new DataContractJsonSerializer(typeof(S2));
S2 r2 = (S2)d2.ReadObject(new MemoryStream(Encoding.Default.GetBytes(simple2)));
Console.WriteLine("done");
Console.ReadKey();
}
[DataContract]
class S1 {
[DataMember]
List<List<String>> aOa;
}
[DataContract]
class S2 {
[DataMember]
List<List<List<string>>> aOaOa;
}
}
Whats the best way to save variables like userid that is stored and reachable from different pages in WP7.
There's the querystring method, but can be kind of a pain to implement.
When navigating, pass the parameter like a HTTP querystring.
Then, on the otherside, check if the key exists, and extract the value. The downside of this is if you need to do more than 1, you need to type it in yourself, and it only supports strings.
So to pass an integer, you'd need to convert it. (And to pass a complex object, you need to take all the pieces you need to recompile it on the other side)
NavigationService.Navigate(new Uri("/PanoramaPage1.xaml?selected=item2", UriKind.Relative));
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
string selected = String.Empty;
//check to see if the selected parameter was passed.
if (NavigationContext.QueryString.ContainsKey("selected"))
{
//get the selected parameter off the query string from MainPage.
selected = NavigationContext.QueryString["selected"];
}
//did the querystring indicate we should go to item2 instead of item1?
if (selected == "item2")
{
//item2 is the second item, but 0 indexed.
myPanorama.DefaultItem = myPanorama.Items[1];
}
base.OnNavigatedTo(e);
}
Here's a sample app that uses a querystring.
http://dl.dropbox.com/u/129101/Panorama_querystring.zip
A easier (and better) idea is to define a variable globally, or use a static class. In App.xaml.cs, define
using System.Collections.Generic;
public static Dictionary<string,object> PageContext = new Dictionary<string,object>;
Then, on the first page, simply do
MyComplexObject obj;
int four = 4;
...
App.PageContext.Add("mycomplexobj",obj);
App.PageContext.Add("four",four);
Then, on the new page, simply do
MyComplexObj obj = App.PageContext["mycomplexobj"] as MyComplexObj;
int four = (int)App.PageContext["four"];
To be safe, you should probably check if the object exists:
if (App.PageContext.ContainsKey("four"))
int four = (int)App.PageContext["four"];
You may use an App level variable (defined in App.xaml.cs) and access it from anywhere within your app. If you want to persist, shove it into Isolated Storage and read it on App launch/activate. There are helpers available to JSon serialize/deserialize your reads/writes from the Isolated Storage.
Check out Jeff's post (here) on tips to use Isolated Storage.
Hope this helps!
Well "best" is always subjective, however, I think an application service is a good candidate for this sort of thing:-
public interface IPhoneApplicationService : IApplicationService
{
string Name {get; set;}
object Deactivating();
void Activating(object state);
}
public class AuthenticationService : IPhoneApplicationService
{
public static AuthenticationService Current {get; private set; }
public void StartService(ApplicationServiceContext context)
{
Current = this;
}
public void StopService()
{
Current = null;
}
public string Name {get; set;}
public object Deactivating()
{
// Return an serialisable object such as a Dictionary if necessary.
return UserID;
}
public void Activating(object state)
{
UserID = (int)state;
}
public int UserID { get; private set; }
public void Logon(string username, string password)
{
// Code here that eventually assigns to UserID.
}
}
You place an instance of this in your App.xaml:-
<Application.ApplicationLifetimeObjects>
<!--Required object that handles lifetime events for the application-->
<shell:PhoneApplicationService
Launching="Application_Launching" Closing="Application_Closing"
Activated="Application_Activated" Deactivated="Application_Deactivated"/>
<local:AuthenticationService Name="AuthServ" />
</Application.ApplicationLifetimeObjects>
Now you do need to tweak the App.xaml.cs:-
private void Application_Activated(object sender, ActivatedEventArgs e)
{
var state = PhoneApplicationService.Current.State;
foreach (var service in ApplicationLifetimeObjects.OfType<IPhoneApplicationService>())
{
if (state.ContainsKey(service.Name))
{
service.Activating(state[service.Name]);
}
}
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
var state = PhoneApplicationService.Current.State;
foreach (var service in ApplicationLifetimeObjects.OfType<IPhoneApplicationService>())
{
if (state.ContainsKey(service.Name))
{
state[service.Name] = service.Deactivating();
}
else
{
state.Add(service.Name, service.Deactivating());
}
}
}
You can now access you UserID anywhere in your app with:-
AuthenticationService.Current.UserID
This general pattern can be used to maintain seperation of key application wide services (you don't load a whole bunch of incohesive properties into your App class). It also provides the hooks for maintaining state between activations which is essential.