2012-08-16 9 views
10

Ho avuto un ciclo morto in un'applicazione webview Android con backkey mentre si occupava di collegamenti di reindirizzamento.Dead loop in android webview backkey per il collegamento href redirect

Ad esempio, quando la mia Webview è iniziata, va a link0.

Nel link0, c'è un collegamento href che collega a link1. Link1 redrect to link2.

Quindi, se faccio clic su link1, andrà a link1, quindi reindirizzare a link2. Quando faccio clic su backkey, dovrebbe tornare a link0, nel mio caso. Invece, va a link1, che reindirizza nuovamente a link2. Quindi non ho mai avuto la possibilità di tornare indietro.

Il backkey funziona correttamente con altri collegamenti se non sono collegamenti di reindirizzamento.

Ho cercato su Google webs, ma non ho trovato la domanda correlata.

A proposito, il backkey funziona nel browser Internet come previsto. Ma non in webview.

Di seguito è riportato il mio codice, da provare. Come puoi vedere nel codice, ho provato sia suBackPressed che onKeyDown, ma neigher funziona.

Grazie per il gentile aiuto. Mi sto battendo per un po '.

========================================= ====================================

public class MyActivity extends Activity 
{ 
    private WebView myWebView; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     myWebView = (WebView) findViewById(R.id.webview); 
     myWebView.getSettings().setJavaScriptEnabled(true); 
     myWebView.loadUrl("http://50.112.242.120/temp/"); 
     myWebView.setWebViewClient(new MyWebViewClient()); 
    } 

    private class MyWebViewClient extends WebViewClient { 
     @Override 
     public boolean shouldOverrideUrlLoading(WebView view, String url) { 
      myWebView.loadUrl(url); 
      return true; 
     } 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     // Check if the key event was the Back button and if there's history 
     if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) { 
      myWebView.goBack(); 
      return true; 
     } 
     // If it wasn't the Back key or there's no web page history, bubble up to the default 
     // system behavior (probably exit the activity) 
     return super.onKeyDown(keyCode, event); 
    } 
} 

.

// main.xml 
<?xml version="1.0" encoding="utf-8"?> 
<WebView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/webview" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
/> 
+0

sei arrivato da qualche parte con questo? –

+0

Quando si dice "link di reindirizzamento" si intende un reindirizzamento HTTP 302 o client con tag Javascript o META expires? –

risposta

1

shouldOverrideUrlLoading() viene chiamato per URL. Quindi, se http://site1.com/ reindirizza a http://site2.com/, che quindi reindirizza a http://site3.com/, stai chiamando WebView.loadUrl() per ognuno di questi URL. Quindi ognuno appare nello stack posteriore.

Invece di creare un WebViewClient probabilmente si desidera un WebChromeClient. WebChromeClient definisce un metodo onCreateWindow che viene richiamato solo quando WebView tenta di creare una nuova finestra, non per ogni singolo URL a cui accede.

+1

Probabilmente perché vogliono che il link si apra nella stessa WebView e non una nuova attività del browser? Penso che sia la solita ragione per scavalcare quel metodo. – Cephron

+0

Ma dal momento che sta iniziando una nuova navigazione per ogni URL nella catena di reindirizzamento, non dovrebbe sorprendere che WebView tratti ogni navigazione separatamente durante il backup. –

+0

È interessante! Cosa intendi con "iniziare una nuova navigazione"? È la chiamata myWebView.loadUrl() in shouldOverrideEtc. metodo? C'è un modo per seguire un reindirizzamento senza avviare una nuova navigazione? – Cephron

0

I fastidiosi reindirizzamenti entrano nella cronologia di backforward. Rileva quando l'url di caricamento viene attivato dall'utente e lo aggiunge invece al backstack.

private List<String> previous = new ArrayList<String>(); 
private String mLastUrl; 
webview.setWebViewClient(new WebViewClient() { 
    @Override 
    public void onPageFinished(WebView view, String url) { 
     Log.i("DebugDebug", "OnPageFinished " + url); 
     mLastUrl = url; 
     super.onPageFinished(view, url); 
    } 
}); 

webview.setOnTouchListener(new View.OnTouchListener() { 
    @Override 
    public boolean onTouch(View view, MotionEvent motionEvent) { 
     WebView.HitTestResult hr = ((WebView)view).getHitTestResult(); 
     if (hr != null && mLastUrl != null) { 
      if (previous.isEmpty() || !previous.get(previous.size() - 1).equals(mLastUrl)) { 
       previous.add(mLastUrl); 
      } 
      Log.i("DebugDebug", "getExtra = " + hr.getExtra() + "\t\t Type = " + hr.getType()); 
     } 
     return false; 
    } 
}); 


@Override 
public void onBackPressed() { 
    Log.i("DebugDebug", "onBackPressed"); 
    int size = previous.size(); 
    if (size > 0){ 
     webview.loadUrl(previous.get(size - 1)); 
     previous.remove(size - 1); 
    } else { 
     super.onBackPressed(); 
    } 
} 
1

avevo una stesso problema e risolto. Qui è my answer.

Quando faccio clic sul primo collegamento (www.new.a), esso reindirizza automaticamente l'altro link (mobile.new.a). Di solito i collegamenti reindirizzano due o tre e la mia soluzione è stata elaborata su quasi tutti i collegamenti di reindirizzamento. Spero che questa risposta ti aiuti con annyo reindirizzamento dei link.

Finalmente ho capito. È necessario un WebViewClient con quattro API. Ci sono shouldOverrideUrlLoading(), onPageStarted(), onPageFinished() e doUpdateVisitedHistory() nel WebViewClient. Tutte le API di cui hai bisogno sono le API 1 quindi non preoccuparti.

Qui è my answer.Dai un'occhiata! :)

3
webview.setWebViewClient(new WebViewClient(){ 
     @Override 
     public boolean shouldOverrideUrlLoading(WebView view, String url) { 
      Log.i(tag, "url = " + url); 
      // view.loadUrl(url); 

      // return super.shouldOverrideUrlLoading(view, url); 
      return false; 
     } 
    }); 

sguardo !!!! l'importante, shouldOverrideUrlLoading deve restituire false

in shouldOverrideUrlLoading non è possibile richiamare view.loadUrl.

+0

Dio, grazie mille, stavo avendo questo problema! Quindi immagino che se caricassimo la webview su quella funzione, in pratica ripristinerà la cronologia di quella webview. – Damiii

Problemi correlati