जब JSON फ़ाइल में कोई नहीं है और केवल ऑब्जेक्ट प्राप्त होता है तो सरणी कैसे बनाएं

मैं एक ऐसा ऐप बनाने की कोशिश कर रहा हूं जो एंड्रॉइड पर यूआरएल से डेटा प्राप्त करे। मैंने देखा कि जेएसओएन फाइलें अलग हैं। उनमें से कुछ एक arrach नाम से शुरू करते हैं और कुछ नहीं। जिनके पास सरणी नाम है इस तरह जो "उपयोगकर्ता" सरणी नाम मेरे ऐप में काम करता है लेकिन जिनके पास कोई सरणी नाम नहीं है, वे काम नहीं करते हैं। उदाहरण के लिए यह

यह वह कोड है जिसे मैं किसी ऑब्जेक्ट को सरणी बनाने का प्रयास करता हूं लेकिन यह दूसरी JSON फ़ाइल के लिए काम नहीं करता है क्योंकि इसे सरणी नाम नहीं मिलता है:

//URL to get JSON Array
private static String url = "http://api.worldbank.org/countries/ir?format=json";

//JSON Node Names 
private static final String TAG_USER = "user";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";

JSONArray user = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

   //Creating new JSON Parser
    JSONParser jParser = new JSONParser();

   //Getting JSON from URL
    JSONObject json = jParser.getJSONFromUrl(url);

    try {
       //Getting JSON Array
        user = json.getJSONArray(TAG_USER);
        JSONObject c = user.getJSONObject(0);

       //Storing  JSON item in a Variable
        String id = c.getString(TAG_ID);
        String name = c.getString(TAG_NAME);
        String email = c.getString(TAG_EMAIL);

        //Importing TextView
        final TextView uid = (TextView)findViewById(R.id.uid);
        final TextView name1 = (TextView)findViewById(R.id.name);
        final TextView email1 = (TextView)findViewById(R.id.email);

        //Set JSON Data in TextView
        uid.setText(id);
        name1.setText(name);
        email1.setText(email);

} catch (JSONException e) {
    e.printStackTrace();
}

}

तो यह उदाहरण पहले JSON भाग के लिए है। क्या आप मुझे बता सकते हैं कि समान कोड कैसे है लेकिन दूसरी JSON फ़ाइल के लिए कृपया?

0
जोड़ा संपादित
विचारों: 1
@ ऑक्टोशप बस कोई भी। मैं केवल इस तरह की फाइलों से निपटना सीखना चाहता हूं जिनमें एरे हैं और ऑब्जेक्ट नहीं है। मुझे डेटा, आईडी, नाम, क्षेत्र, iso2Code मिल जाएगा
जोड़ा लेखक user2977338, स्रोत
चूंकि यह प्रश्न AsyncTask के बारे में अधिक है और इस ऐप की सरणी समस्या नहीं है। मैं विशेष रूप से सरणी समस्या के लिए एक नई पोस्ट बनाने जा रहा हूं।
जोड़ा लेखक user2977338, स्रोत
@ ऑक्टोशिप आपकी मदद के लिए धन्यवाद। मैंने आपके समाधान की कोशिश की दुर्भाग्य से काम नहीं किया। यह बहुत अच्छा होगा अगर आप AsyncTask के लिए कुछ नमूना कोड प्रदान करते हैं क्योंकि मुझे इसके बारे में कोई जानकारी नहीं है। एक भी क्यों learn2crack इसे asyncTask का उपयोग नहीं किया? वह क्या इस्तेमाल करता है एक अलग तरीका है? या क्योंकि जेसन फ़ाइल छोटी है?
जोड़ा लेखक user2977338, स्रोत
@ ऑक्टोशिप हां मैं learn2crack लाइब्रेरी का उपयोग कर रहा हूं। लेकिन मैंने देखा कि अधिकांश JSONParser के HTTP के लिए एक ही कोड है।
जोड़ा लेखक user2977338, स्रोत
@ ऑक्टोशिप हां यह catlog है: अंतिम अपवाद: मुख्य java.lang.RuntimeException: गतिविधि शुरू करने में असमर्थ ComponentInfo {com.example.worldbank/com.example.worldbank.Ma और zwnj; inctivity}: android.os.NetworkOnMainThreadException लेकिन मैं समस्या का विश्वास करता हूं जिस तरह से मैं सरणी और वस्तुओं को बनाता हूं।
जोड़ा लेखक user2977338, स्रोत
@ user2977338 मैं अपने जवाब में AsyncTask को अधिक विस्तृत समझाऊंगा, यह learn2crack के कोड में कुछ भी गलत नहीं है। मैं इसे समझाऊंगा।
जोड़ा लेखक Octoshape, स्रोत
दूसरी फाइल से कौन से इंफोस आप रुचि रखते हैं?
जोड़ा लेखक Octoshape, स्रोत
तो क्या आप अब AsyncTask चल रहे हैं? अगर आप एक उत्तर चुन सकते हैं तो खुशी होगी :)
जोड़ा लेखक Octoshape, स्रोत
क्या आप JSONParser के लिए learn2crack लाइब्रेरी का उपयोग कर रहे हैं या आपने खुद को एक लिखा है?
जोड़ा लेखक Octoshape, स्रोत
@ user2977338 मैंने अपना उत्तर अपडेट कर लिया है, संपादित करें और [/ EDIT] के बीच अनुभाग देखें।
जोड़ा लेखक Octoshape, स्रोत
आह मैं देखता हूं .. हाँ आपको AsyncTasks का उपयोग करने की आवश्यकता है, लेकिन पार्सर JSONArrays को भी पार्स नहीं कर सकता .. मैं नीचे दिए गए मेरे उत्तर में दोनों समस्याओं का समाधान शामिल करूंगा।
जोड़ा लेखक Octoshape, स्रोत
ठीक है .. मैं उनके पार्सर पर एक नज़र डालूंगा .. क्या आप दूसरी फाइल के लिए यूआरएल कोशिश करते समय कोई अपवाद प्राप्त करते हैं?
जोड़ा लेखक Octoshape, स्रोत
@ user2977338 यदि आपको AsyncTask चीज़ पर शुरू करने के लिए कुछ नमूना कोड की आवश्यकता है तो मुझे बताएं कि मैं नीचे दिए गए मेरे उत्तर में कुछ जोड़ सकता हूं।
जोड़ा लेखक Octoshape, स्रोत
@ user2977338 आप या तो ऑक्टोशप या मेरे समाधान का उपयोग कर सकते हैं। दोनों समाधानों की अपनी विशिष्टता है :)
जोड़ा लेखक saiful103a, स्रोत
@ user2977338 आपको थ्रेड/एसिन्टास्क का उपयोग करना होगा जब आप ऑक्टोशिप के सुझाव के अनुसार कोई नेटवर्क ऑपरेशन करते हैं।
जोड़ा लेखक saiful103a, स्रोत

2 उत्तर

तो सबसे पहले आपको मुख्य धागे पर नेटवर्क सामान करने की अनुमति नहीं है क्योंकि उन चीजों में लंबा समय लगता है (यदि सर्वर प्रतिक्रिया नहीं दे रहा है या कनेक्शन खराब है या जिस फ़ाइल को आप लाने की कोशिश कर रहे हैं वह बड़ा है) और यदि किया जाता है मुख्य धागे पर यह फोन पर एप्लिकेशन को अवरुद्ध कर देगा। यदि आपका ऐप बहुत लंबे समय तक उत्तरदायी नहीं है तो यह एंड्रॉइड ओएस से स्वचालित रूप से मारा जाएगा। ऐसी चीजों से बचने के लिए आपको AsyncTasks का उपयोग करने की आवश्यकता है। ये वे कार्य हैं जो पृष्ठभूमि में काम कर सकते हैं जबकि आपका मुख्य थ्रेड अभी भी उपयोगकर्ता इनपुट के लिए उत्तरदायी है।

आप AsyncTasks यहां के बारे में अधिक पढ़ सकते हैं।

[संपादित करें] तो आपके प्रश्न पर आपकी टिप्पणी का उत्तर दें: कारण आपको NetworkOnMainThreadException क्यों मिलता है क्योंकि आप jParser.getJSONFromUrl (url) को कॉल करते हैं; अपने मुख्य थ्रेड में (जहां आप सामान्य रूप से कोड निष्पादित करें)। इसका कारण क्यों नहीं है क्योंकि विधि getJSONFromUrl() विधि में आप एक HTTP अनुरोध करते हैं और दिए गए यूआरएल से प्रतिक्रिया के लिए इंतजार करना पड़ता है। इसमें बहुत लंबा समय लग सकता है जैसा कि मैंने उपरोक्त समझाया है और पहले से ही समझाए गए परिणामों के साथ फोन पर अपने आवेदन को अवरुद्ध कर देगा। अब इसे ठीक करने के लिए आपको ऐसा कुछ करने की ज़रूरत है:

इससे पहले (खराब):

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// Creating new JSON Parser
JSONParser jParser = new JSONParser();

// Getting JSON from URL
JSONObject json = jParser.getJSONFromUrl(url);

// get the data from your JSONObject

}

बेहतर:

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// Getting JSON from URL
new JsonRequest().execute(url);

}

private class JsonRequest extends AsyncTask
// I will talk about the parameters to AsyncTask below
    @Override
    protected JSONObject doInBackground(String... urls) {
       //Creating new JSON Parser
        JSONParser jParser = new JSONParser();

       //Getting JSON from URL
        JSONObject json = jParser.getJSONFromUrl(url);

        return json;
    }


    @Override
    protected void onPostExecute(JSONObject result) {

       //Get the array
        JSONArray array = result.getJSONArray("data");

       //Display the data
       //Import textviews
       //and so on..
    }

अब पैरामीटर के बारे में AsyncTask :

  1. This type is the type of the parameters given to doInBackground
  2. This type is used for showing a progress bar for example if you download many things you can override a function called onProgressUpdate and could show how many things already have been downloaded on your app so the user knows that something is happening.
  3. This type is the type that doInBackground will return and that onPostExecute has as a parameter.

इस प्रकार आपका मुख्य धागा चल रहा रहेगा और उपयोगकर्ता इस बात की कोई सूचना नहीं देगा कि पृष्ठभूमि में एक डाउनलोड चल रहा है क्योंकि यह एक अलग कार्य है जो चल रहा है। मुझे उम्मीद है कि अगर यह नहीं है तो यह स्पष्ट हो गया है, बस एक और टिप्पणी छोड़ दो और मैं और समझाऊंगा। :)

[\ संपादित करें]

फिर दूसरी समस्या यह है कि learn2crack से JSONParser JSONArrays को पार्स नहीं कर सकता है, दूसरे शब्दों में फ़ंक्शन getJSONFromUrl() बस एक नया JSONObject </कोड> स्ट्रिंग से यह दिए गए यूआरएल से मिलता है।

मूल रूप से इसे ठीक करने के कई तरीके हैं, मैंने थोड़ा हैक किया है (यह थोड़ा कोड चालित करता है लेकिन आपको बाद में डेटा प्राप्त करने में अधिक समय की आवश्यकता होगी)। मैंने निम्नलिखित पंक्तियों को getJSONFromUrl() विधि में जोड़ा:

if (json.startsWith("[")) {
   //We have a JSONArray
    try {
        jObj = new JSONObject();
        jObj.put("data", new JSONArray(json));
    } catch (JSONException e) {
        Log.d("JSON Parser", "Error parsing JSONArray " + e.toString());
    }
    return jObj;
}

इन पंक्तियों को इस भाग से ऊपर जोड़ा जाना चाहिए:

// try parse the string to a JSON object
try {
    jObj = new JSONObject(json);
} catch (JSONException e) {
    Log.e("JSON Parser", "Error parsing data " + e.toString());
}

असल में आप इसके साथ क्या समाप्त करेंगे यह है कि आप किसी भी यूआरएल पर getJSONFromUrl() को कॉल कर सकते हैं, और यदि इसमें JSONObject है तो आपको वह ऑब्जेक्ट मिलेगा, लेकिन अगर यह एक JSONArray है जिसमें आपको JSONObject एक कोड के साथ डेटा नाम मिलेगा जिसमें आपका JSONArray होगा। तो आप ऐसा कुछ कर सकते हैं:

JSONObject json = jParser.getJSONFromUrl(url);

JSONArray array = json.getJSONArray("data");

और फिर आपके पास सरणी है (निश्चित रूप से JSONException के लिए प्रयास करने के लिए घिरा हुआ है)।

2
जोड़ा
आपके सहयोग के लिए धन्यवाद। वास्तव में सहायक और मेरा ऐप चल रहा है
जोड़ा लेखक user2977338, स्रोत
आपकी पोस्ट के लिए धन्यवाद। केवल एक सवाल है। मैंने if-statement और कोशिश करें {jObj .... getJSONFromUrl विधि में जोड़ा। लेकिन यह json और jObj जैसे त्रुटि के साथ आया और परिभाषित नहीं किया गया है। ऐसा क्यों है ?
जोड़ा लेखक user2977338, स्रोत
@ user2977338 क्या आप कृपया मुझे अपने प्रश्न में अपना पूरा getJSONFromUrl विधि कोड पोस्ट कर सकते हैं?
जोड़ा लेखक Octoshape, स्रोत
मुझे तुम्हारा समाधान भी पसंद आया, मैं इंटरफ़ेस के मामले में और सोच रहा था, इसलिए मैं getJSONFromUrl से दो ऑब्जेक्ट की बजाय एक ऑब्जेक्ट वापस कर सकता हूं। आपका एक छोटा रास्ता है :)
जोड़ा लेखक saiful103a, स्रोत

जहां तक ​​मुझे पता है कि यह जानने के लिए कोई विशिष्ट तरीका नहीं है कि आप इसे पार्स करने के बाद जेसन सरणी या जेसन ऑब्जेक्ट प्राप्त कर रहे हैं !!!

जिस तरह से मैं इसे हल करूँगा, प्रतिक्रिया से स्ट्रिंग डेटा के प्रारंभिक चरित्र को देखना है।

आपके getJSONFromUrl विधि में आपको प्रतिक्रिया से स्ट्रिंग मिलती है और फिर आप उसे JsonObject में पार्स करना शुरू कर देते हैं। शुरुआती चरित्र के आधार पर चरित्र शुरू करने के लिए पार्स से पहले यह तय करें कि आप जेसनऑब्जेक्ट या जेसनअरे के लिए जा रहे हैं या नहीं।

मुझे यकीन नहीं है कि क्या यह हल करने का उनका कोई छोटा रास्ता है, लेकिन आपकी समस्या एक मुश्किल है :)। कई अन्य चीजों को निपटाया जाना चाहिए क्योंकि आप वास्तव में पहले से नहीं जानते हैं कि क्या आप jsonobject या jsonarray प्राप्त करने जा रहे हैं।

यहां मैंने जो कुछ रखा है वह यहां है:

public interface JsonListener {

     public boolean isJsonObejct();

}

JSONObject को विस्तारित करके और उपरोक्त इंटरफ़ेस को कार्यान्वित करके कक्षा बनाएं।

import org.json.JSONException;
import org.json.JSONObject;

public class CustomJSONObject extends JSONObject implements JsonListener {

public CustomJSONObject(String json) throws JSONException {
   //TODO Auto-generated constructor stub
    super(json);
}

@Override
public boolean isJsonObejct() {
   //TODO Auto-generated method stub
    return true;
}

 }

JSONArray को विस्तारित करके और उपरोक्त इंटरफ़ेस को कार्यान्वित करके एक और कक्षा बनाएं।

import org.json.JSONArray;
import org.json.JSONException;

public class CustomJSONArray extends JSONArray implements JsonListener{

public CustomJSONArray(String json) throws JSONException {
   //TODO Auto-generated constructor stub
    super(json);
}

@Override
public boolean isJsonObejct() {
   //TODO Auto-generated method stub
    return false;
}

 }

आपको jsonparseclass संशोधित करें, इसलिए यह jsonobject या jsonarray को वापस नहीं करता है बल्कि यह ऑब्जेक्ट ऑफ जेसन लिस्टनर लौटाएगा।

public class JSONParser {

static InputStream is = null;
static JsonListener jObj = null;
static String json = "";

// constructor
public JSONParser() {

}

public JsonListener getJSONFromUrl(String url) {

   //Making HTTP request
    try {
       //defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();           

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

   //try parse the string to a JSON object
    try {
        if(json.startsWith("{")){
            jObj = new CustomJSONObject(json);
        }else{
            jObj = new CustomJSONArray(json);
        }

    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

   //return JSON String
    return jObj;

}
 }

अब उनका उपयोग करने के लिए अपने कोड को समायोजित करें:

// Creating new JSON Parser
            JSONParser jParser = new JSONParser();

           //Getting JSON from URL
            JsonListener json = jParser.getJSONFromUrl(url);
            if(json.isJsonObejct()){
                Log.i("Got","JsonObject "+((CustomJSONObject)json).toString());
            }else{
                Log.i("Got","JsonArray "+((CustomJSONArray)json).toString());
            }   

उम्मीद है कि आप इससे कुछ अंतर्दृष्टि प्राप्त करेंगे।

2
जोड़ा
आपकी पोस्ट के लिए धन्यवाद। लेकिन यह काम नहीं आया। यह सुनिश्चित करने के लिए बस कुछ प्रश्न हैं कि मैंने इसे सही तरीके से किया है। मुझे अपना JSONListener कहां जोड़ना चाहिए? मैं इसे मुख्य_एक्टिविटी के अंत में जोड़ता हूं। और मुझे इस लाइन को भी हटा देना चाहिए? value = json.getJSONArray (VALUE);
जोड़ा लेखक user2977338, स्रोत
@ saiful103a विज्ञापन के लिए धन्यवाद: डी मैं अभी भी जेसन लिस्टनर लौटकर सामान्यता के कारण मेरा समाधान पसंद करता हूं ...
जोड़ा लेखक Octoshape, स्रोत
इंटरफेस का अच्छा उपयोग। विचार की तरह!
जोड़ा लेखक Octoshape, स्रोत
JSONListener एक अलग फ़ाइल होगी। और जेसन से डेटा प्राप्त करने के लिए आपको ((कस्टमजेसनऑब्जेक्ट) जेसन का उपयोग करना होगा) .get [आपको आवश्यक डेटा का प्रकार] या ((कस्टमजेसनऑरे) जेसन) .get [आपको आवश्यक डेटा का प्रकार]। आपको दस्तावेज में सभी गेटर्स मिलेंगे। मुझे लगता है कि अगर आप @ ऑक्टोशप समाधान का उपयोग करते हैं तो यह बेहतर होगा क्योंकि यह आपके कोड लिखने के लिए बहुत हल्का है। लेकिन यह जानना कि आप इस तरह की स्थिति में इंटरफ़ेस का लाभ कैसे ले सकते हैं, आप इसका उपयोग कर सकते हैं। :)
जोड़ा लेखक saiful103a, स्रोत