【Android】WebViewのロード完了までプログレスダイアログを表示する
WebViewに限ったことではないですが、重たい処理を実行中にローディング中であることを示すダイアログを表示する方法のまとめです。
画面の初期化やファイルの読み込み・書き込みなど様々な用途に応用できます。
今回はWebViewClientを継承したクラスを作ってonPageFinished()メソッドなどを実装します。
実装
プログレスダイアログの生成
変数(progressDialog)はメンバ変数、もしくはfinalで宣言する必要があります。理由はダイアログを閉じる時にメインスレッドとは別のスレッドからアクセスすることになるのでメソッド内のローカル変数だとエラーになります。
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.show();
プログレスダイアログの表示開始と主処理開始
HandlerクラスはUIスレッド(つまりメインスレッド)へRunnableを渡してUIや画面側を処理することが来ます。ここではWebViewのローディングと、その中のonPageFinishedメソッドでダイアログの停止を行っています。
// スレッド内でプログレスダイアログを閉じるためにHandlerを生成
final Handler handler = new Handler();
// スレッド処理
new Thread(new Runnable() {
@Override
public void run() {
try {
handler.post(new Runnable() {
@Override
public void run() {
// ※ここで本来行いたい処理をする
webView.loadUrl("https://news.google.com/");
}
});
} catch (Exception e) {
Log.d("ERROR", e.getMessage());
}
}
}).start();
WebViewClientを継承したクラス
内部クラスで定義し、ページのロード処理が完了したらonPageFinishedメソッド内でダイアログを閉じるように処理を入れます。
これを生成した変数はsetWebViewClientでセットし、メインスレッドとは別でロードしてやります。
public final class MyViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view , String url){
if(progressDialog.isShowing()) {
progressDialog.dismiss();
}
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
webView.stopLoading();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return false;
}
});
}
}
ソースコード全体
MainActivity.java
ソースコード全体としは、以下のような感じです。
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
ProgressDialog progressDialog;
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// プログレスダイアログを生成・表示
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.show();
// WebViewインスタンスを生成
webView = findViewById(R.id.webviewTest);
webView.clearCache(true);
// WebViewClientを継承した独自クラスをセット
webView.setWebViewClient(new MyViewClient());
// スレッド内でプログレスダイアログを閉じるためにHandlerを生成
final Handler handler = new Handler();
// スレッド処理
new Thread(new Runnable() {
@Override
public void run() {
try {
handler.post(new Runnable() {
@Override
public void run() {
webView.loadUrl("https://news.google.com/");
}
});
} catch (Exception e) {
Log.d("ERROR", e.getMessage());
}
}
}).start();
}
public final class MyViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view , String url){
if(progressDialog.isShowing()) {
progressDialog.dismiss();
}
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
webView.stopLoading();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return false;
}
});
}
}
}
実行結果
アプリケーションを実行するとまずはじめにダイアログが表示され、WebViewのローディングと同時にダイアログが消えて画面の操作が可能になります。 |
備考
WebViewのLoad処理でnet:ERR_CACHE_MISSが発生する場合
この問題はパーミッションが足りていないだけで、AndroidManifest.xml に以下を追加するだけで解消します。
<uses-permission android:name="android.permission.INTERNET" />
net:ERR_CACHE_MISSというエラーではPermissionの問題だとピンと来ずに少し嵌りかけたのでメモしておきます。
コメント
コメントを投稿