2014-04-25 1 views
0

효율성을 높이기 위해 가능한 한 서버에 액세스하려고합니다. 내가 가지고있는 if-elseif-else 블록으로이 일을 처리했다고 생각했지만, 여전히 내가 원하는 것보다 더 많은 시간이 걸린다. 이것이 개선 될 수있는 방법이 있습니까? 현재의 양식에서는이 섹션을 진행하는 데 2 ​​분 이상이 소요됩니다. 나는 가능한 한 빨리 그것을 좋아할 것이 분명하다.JSON 구문 분석 최적화 - ID와 연결된 이름 가져 오기

JSON에서 룰 (rune) 번호 만 독점적으로 반환하면 즉시 적용됩니다. 그러나 내가해야 할 일은 ID와 관련된 이름을 찾아서 반환하는 것입니다. 코드 섹션에서 traceview를 수행하고 아래에 포함 시켰습니다. 그것을 읽는 방법을 잘 모르겠지만 잘못 섹션 ID (getRuneInfo)에서 이름을 얻는 나의 방법입니다 확신합니다.

궁극적으로, ID 이름 쌍이 로컬에 저장되므로 시간이 지남에 따라 서버에 로컬로이 정보를 저장하는 것이 좋습니다. 어떻게해야할지 모르겠습니다.

Traceview 파일 : https://www.dropbox.com/s/4fc6kdk35wackwr/RuneLoop.trace

루프 :

// Loop through pages, page names stored in string array 
for (int i = 0; i < rune.length(); i++) { 
    JSONObject c = rune.getJSONObject(i); 
    JSONArray slots = c.getJSONArray(TAG_SLOTS); 
    name[i] = c.getString(TAG_NAME); 

    // This loop is where the slowdown is. Before I added this 
    // the code ran very quickly. 
    for (int x = 0; x < 27; x++) { 
     JSONObject s = slots.getJSONObject(x); 

     if (Integer.valueOf(s.getString(TAG_RUNEID)).equals(prevId)) { 
      runesArray[i][x] = runesArray[i][x - 1]; 
      prevId = Integer.valueOf(s.getString(TAG_RUNEID)); 
     } else if (Integer.valueOf(s.getString(TAG_RUNEID)).equals(runeIdArray[Integer.valueOf(s.getString(TAG_RUNEID))])) 
      runesArray[i][x] = runeIdArray[Integer.valueOf(s.getString(TAG_RUNEID))]; 

     else 
      // I believe the slowdown stems specifically from this 
      runesArray[i][x] = getStaticData.getRuneInfo(s.getString(TAG_RUNEID)); 
      runeIdArray[Integer.valueOf(s.getString(TAG_RUNEID))] = runesArray[i][x]; 
    } 

getRuneInfo 방법 :

public String getRuneInfo(String runeId) { 
     String name = null; 
     try { 
      name = new GetRunes() 
        .execute(runeId) 
        .get(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      e.printStackTrace(); 
     }  
     return name; 
    } 

else 문이 시작되는 getRuneInfo를 호출합니다. 나는 모든 가져 오기가 그것을 느리게한다고 믿습니다. GetRunes :

public static class GetRunes extends AsyncTask<String, String, String> { 

     protected String doInBackground(String[] runeId) { 
      String url = "https://prod.api.pvp.net/api/lol/static-data/" + region + "/v1.2/rune/" + runeId[0] + "?api_key=" + api_key; 
      JSONParser jsonParser = new JSONParser(); 
      JSONObject runeInfo = jsonParser.getJSONFromUrl(url); 
      String name = null; 
      try { 
       name = runeInfo.getString("name"); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
      return name; 
     } 
    } 
+0

귀하의 질문에 명확하지 않습니다. 그래도 재미있는 것 같습니다! 루틴을 완료하는 데 2 ​​분이 걸리는 지점과 ID에 연결된 이름을 가져와야하는 위치를 명확하게 지적 할 수 있습니까? – rupps

+0

@rupps 물론입니다! 내 메인 포스트를 편집하십시오. 편집 : 완료 – Nate

답변

1

는 지금까지 내가 당신이 무엇을하고 있는지 이해, (27 개) 요청이 서버로 전송되는 것 같다, 그래서 이것은 분명 시간이 걸립니다.

요청은 아마도 순차적으로 실행됩니다. 즉, 다른 요청이 완료되면 하나가 시작됩니다.

asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR). 

그러나, 당신이 병렬로 실행할 수 있습니다 얼마나 많은 작업에 한계가있다, 당신은 병렬 실행을 위해 코드를 조금 적응해야합니다 :이 같은 병렬 실행을 가능하게함으로써 시간을 절약 할 수 있습니다. 나는 27 가지 요청이 필요하다면이 외에도 많은 것을 할 수는 없을 것이라고 두려워합니다.

두 번째 질문에 대해서는 요청을 로컬에 저장해야한다는 것이 확실합니다. 가장 쉬운 방법은 GetRunes에받은 모든 JSON을 sdcard의 파일에 저장하는 것입니다. 매우 간단합니다. 에서도 이미 다운로드 한 파일이 있는지 확인하십시오. 이렇게하면 모든 룬을 다운로드하는 데 2 ​​분이 걸릴 수 있지만이 작업은 한 번만 수행해야합니다. 모든 파일이 sdcard에 저장되면 실행은 거의 순간적입니다.

나는 여기에 귀하의 영감을 얻기 위해 물건을 캐시하는 데 사용하는 루틴 하나를 게시합니다. 기본적으로 URL로 호출하고 그 URL을 sdcard에 다운로드하고 URL의 md5 해시 파일 이름에 저장합니다 . 따라서 다운로드하기 전에 요청한 URL의 md5가 캐시에 있는지 확인하고 다운로드 한 경우 다운로드하는 대신 sdcard에서 파일을 읽습니다.

private static boolean cache_url(Context context, String fileurl) throws DeviceNotOnlineException { 

     try { 
       File cacheDir=new File(context.getCacheDir(),"url_cache"); 

      ensureOnline(); 

      if(!cacheDir.exists()) 
       cacheDir.mkdirs(); 

      File f=new File(cacheDir, md5(fileurl)); 
      URL url = new URL(fileurl); 

      InputStream input = new BufferedInputStream(url.openStream()); 
      OutputStream output = new FileOutputStream(f); 

      byte data[] = new byte[16384]; 
      int count=0; 

      if (Conf.LOG_ON) Log.v(TAG, "Caching "+fileurl+" into "+f.getAbsolutePath()); 

      while ((count = input.read(data)) != -1) { 
       output.write(data, 0, count); 
      } 

      output.flush(); 
      output.close(); 
      input.close(); 
      return true; 
     } catch (FileNotFoundException f) { 
      if (Conf.LOG_ON) Log.e(TAG, "WARNING: FILE NOT FOUND! "+f.getMessage()); 
     } catch (Exception e) { 
      if (Conf.LOG_ON) e.printStackTrace(); 
     } 

     return false; 
    } 
+0

데이터를 로컬에 저장하고 앱이 실행될 때마다 액세스하려면 어떻게해야합니까? 또한 내 앱을 망칠 때 화면에 방향이 바뀌면 27 개의 요청이 다시 시작된다는 것을 알게되었습니다. 이것을 막을 수있는 방법이 있습니까? – Nate

+0

getRunes, getJSONfromURL 후 전체 JSON을 파일 및 getRunes에 저장하십시오. befor getJSONFromURL 저장된 버전이 있는지 확인하십시오. – rupps

+0

감사합니다. 내 혼란은 당신이 Strings와 Shared Preferences를 다룰 수 없다고 생각했다. – Nate