2016-06-27 2 views
1

У меня есть странная проблема; если я запустил этот код, я получаю java.io.FileNotFoundException: https://graph.facebook.com/debug_token?input_token=1234&access_token=1234. Это происходит только тогда, когда я вызываю client.getInputStream() внутри своего AsyncTask. Нажмите на ссылку: она работает.
Давайте назовем этот случай 1.java.io.FileNotFoundException возникает только при запуске внутри AsyncTask

Теперь, когда я запускаю тот же код, вне моего AsyncTask, я получаю NetworkOnMainThreadException, но client.getInputStream() работы ...
Рассмотрим случай 2.

я знаю почему я получаю NetworkOnMainThreadException в случае 2, но я не понимаю, почему FileNotFoundException происходит только в случае 1, а не в случае 2. Код идентичен! Я смотрел на это часами, и я просто не знаю, что я делаю неправильно.

РЕДАКТИРОВАТЬ: apperently FileNotFoundException происходит из-за кода ответа на ошибку. Я понял это, получив поток ошибок с .getErrorStream() при возникновении исключения.

import android.os.AsyncTask; 
import android.util.Log; 

import java.io.IOException; 
import java.io.InputStream; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.Scanner; 

import javax.net.ssl.HttpsURLConnection; 

public class Temp { 

    private String getResponse(InputStream stream){ 
     Scanner s = new Scanner(stream).useDelimiter("\\A"); 
     try { 
      stream.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return s.hasNext() ? s.next() : ""; 
    } 

    public void run(String url){ 
     URL uri; 
     HttpsURLConnection client = null; 
     try { 
      uri = new URL(url); 
      client = (HttpsURLConnection) uri.openConnection(); 
      client.setReadTimeout(15*1000); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     new RetrieveStream().execute(client); 
    } 

    private class RetrieveStream extends AsyncTask<HttpsURLConnection, Void, String> { 
     private String returnString = null; //don't change this! 
     HttpsURLConnection client; 
     @Override 
     protected String doInBackground(HttpsURLConnection... client) { 
      try { 
       this.client = client[0]; 
       InputStream stream = this.client.getInputStream(); 
       Log.d(getClass().getSimpleName(), "response: "+getResponse(this.client.getInputStream())); 
      } catch (FileNotFoundException e) { 
       Log.d(getClass().getSimpleName(), "error output: "+getResponse(this.client.getErrorStream())); 
       e.printStackTrace(); 
      } catch (IOException e) { 
       Log.d(getClass().getSimpleName(), "error: "+getResponse(this.client.getErrorStream())); 
       e.printStackTrace(); 
      } 
      this.client.disconnect(); 
      return returnString; 
     } 

     protected void onPostExecute(String output) { 
      Log.d(getClass().getSimpleName(), "output: "+output); 
     } 
    } 
} 
+1

Немного странно, что вы открываете соединение, а затем передаете его в «AsyncTask». Вы пробовали просто передать «URL» в «AsyncTask», а затем выполнили всю инициализацию внутри 'doInBackground()' вместо этого? – NoChinDeluxe

+0

@NoChinDeluxe Это только странно; это пустой пример моего фактического класса, который имеет методы для настройки заголовков, метода запроса и т. д. и т. д. Все это происходит вне контекста «AsyncTask». Но этот минимальный пример все равно не работает. – slinden77

+0

Независимо от того, является ли это реальным кодом или примером, странно, что вы инициализируете соединение OUTSIDE фонового потока, а затем передаете открытое соединение в другой поток. Это странно, и я уверен, что это проблема. Я бы попытался выполнить все ваши инициализации соединения, включая заголовки и все остальное, внутри 'doInBackground()'. – NoChinDeluxe

ответ

0

Это не очень понятно, почему FileNotFoundException происходит, но я был в состоянии получить ответ с .getErrorStream() вместо .getInputStream(). Мой вопрос редактируется соответствующим образом. Пожалуйста, игнорируйте другие ответы, они не дают никаких решений.

0

я не глубоко в андроида развития, но так как тему, кажется, чтобы быть в курсе соединений (подразумеваемые по «NetworkOnMainThreadException»), я хотел бы предложить, чтобы передачи экземпляра URL к вашему AsyncTask и открыть соединение там , а не сдавать клиент.

Помимо этого, читая апи, я бы ожидать

client.connect(); 

перед тем

client.getInputStream(); 

прибудете называеться.

Ссылки:

https://developer.android.com/reference/java/net/URL.html#openConnection() https://developer.android.com/reference/java/net/URLConnection.html#getInputStream()

+0

Привет, спасибо за ответ. Мой класс использует 'javax.net.ssl.HttpsURLConnection', который отличается. Конечно, я попробовал это с помощью «клиента».connect() ', по-прежнему та же ошибка. Передача экземпляра URL также ничего не фиксирует. – slinden77

+0

'.connect' не требуется с java.net.HttpUrlConnection https://developer.android.com/reference/java/net/HttpURLConnection.html, что объясняет, почему он ничего не решает ... – slinden77

Смежные вопросы