Skip to content

Commit 41b363c

Browse files
authored
Show loading screen while unpacking for webview bootstrap (kivy#2153)
* Port unpack task to webview to properly show loading screen. * Remove customization for our own implementation.
1 parent 6781179 commit 41b363c

File tree

1 file changed

+162
-91
lines changed

1 file changed

+162
-91
lines changed

pythonforandroid/bootstraps/webview/build/src/main/java/org/kivy/android/PythonActivity.java

Lines changed: 162 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -109,115 +109,119 @@ public static void initialize() {
109109
protected void onCreate(Bundle savedInstanceState) {
110110
Log.v(TAG, "My oncreate running");
111111
resourceManager = new ResourceManager(this);
112-
113-
Log.v(TAG, "Ready to unpack");
114-
File app_root_file = new File(getAppRoot());
115-
unpackData("private", app_root_file);
116-
117-
Log.v(TAG, "About to do super onCreate");
118112
super.onCreate(savedInstanceState);
119-
Log.v(TAG, "Did super onCreate");
120113

121114
this.mActivity = this;
122-
//this.showLoadingScreen();
123-
Log.v("Python", "Device: " + android.os.Build.DEVICE);
124-
Log.v("Python", "Model: " + android.os.Build.MODEL);
115+
this.showLoadingScreen();
116+
new UnpackFilesTask().execute(getAppRoot());
117+
}
125118

126-
//Log.v(TAG, "Ready to unpack");
127-
//new UnpackFilesTask().execute(getAppRoot());
119+
private class UnpackFilesTask extends AsyncTask<String, Void, String> {
120+
@Override
121+
protected String doInBackground(String... params) {
122+
File app_root_file = new File(params[0]);
123+
Log.v(TAG, "Ready to unpack");
124+
unpackData("private", app_root_file);
125+
return null;
126+
}
128127

129-
PythonActivity.initialize();
128+
@Override
129+
protected void onPostExecute(String result) {
130+
Log.v("Python", "Device: " + android.os.Build.DEVICE);
131+
Log.v("Python", "Model: " + android.os.Build.MODEL);
130132

131-
// Load shared libraries
132-
String errorMsgBrokenLib = "";
133-
try {
134-
loadLibraries();
135-
} catch(UnsatisfiedLinkError e) {
136-
System.err.println(e.getMessage());
137-
mBrokenLibraries = true;
138-
errorMsgBrokenLib = e.getMessage();
139-
} catch(Exception e) {
140-
System.err.println(e.getMessage());
141-
mBrokenLibraries = true;
142-
errorMsgBrokenLib = e.getMessage();
143-
}
133+
PythonActivity.initialize();
144134

145-
if (mBrokenLibraries)
146-
{
147-
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
148-
dlgAlert.setMessage("An error occurred while trying to load the application libraries. Please try again and/or reinstall."
149-
+ System.getProperty("line.separator")
150-
+ System.getProperty("line.separator")
151-
+ "Error: " + errorMsgBrokenLib);
152-
dlgAlert.setTitle("Python Error");
153-
dlgAlert.setPositiveButton("Exit",
154-
new DialogInterface.OnClickListener() {
155-
@Override
156-
public void onClick(DialogInterface dialog,int id) {
157-
// if this button is clicked, close current activity
158-
PythonActivity.mActivity.finish();
159-
}
160-
});
161-
dlgAlert.setCancelable(false);
162-
dlgAlert.create().show();
135+
// Load shared libraries
136+
String errorMsgBrokenLib = "";
137+
try {
138+
loadLibraries();
139+
} catch(UnsatisfiedLinkError e) {
140+
System.err.println(e.getMessage());
141+
mBrokenLibraries = true;
142+
errorMsgBrokenLib = e.getMessage();
143+
} catch(Exception e) {
144+
System.err.println(e.getMessage());
145+
mBrokenLibraries = true;
146+
errorMsgBrokenLib = e.getMessage();
147+
}
163148

164-
return;
165-
}
149+
if (mBrokenLibraries)
150+
{
151+
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(PythonActivity.mActivity);
152+
dlgAlert.setMessage("An error occurred while trying to load the application libraries. Please try again and/or reinstall."
153+
+ System.getProperty("line.separator")
154+
+ System.getProperty("line.separator")
155+
+ "Error: " + errorMsgBrokenLib);
156+
dlgAlert.setTitle("Python Error");
157+
dlgAlert.setPositiveButton("Exit",
158+
new DialogInterface.OnClickListener() {
159+
@Override
160+
public void onClick(DialogInterface dialog,int id) {
161+
// if this button is clicked, close current activity
162+
PythonActivity.mActivity.finish();
163+
}
164+
});
165+
dlgAlert.setCancelable(false);
166+
dlgAlert.create().show();
167+
168+
return;
169+
}
166170

167-
// Set up the webview
168-
String app_root_dir = getAppRoot();
171+
// Set up the webview
172+
String app_root_dir = getAppRoot();
169173

170-
mWebView = new WebView(this);
171-
mWebView.getSettings().setJavaScriptEnabled(true);
172-
mWebView.getSettings().setDomStorageEnabled(true);
173-
mWebView.loadUrl("file:///" + app_root_dir + "/_load.html");
174+
mWebView = new WebView(PythonActivity.mActivity);
175+
mWebView.getSettings().setJavaScriptEnabled(true);
176+
mWebView.getSettings().setDomStorageEnabled(true);
177+
mWebView.loadUrl("file:///" + app_root_dir + "/_load.html");
174178

175-
mWebView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
176-
mWebView.setWebViewClient(new WebViewClient() {
177-
@Override
178-
public boolean shouldOverrideUrlLoading(WebView view, String url) {
179-
view.loadUrl(url);
180-
return false;
181-
}
182-
});
183-
mLayout = new AbsoluteLayout(this);
184-
mLayout.addView(mWebView);
179+
mWebView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
180+
mWebView.setWebViewClient(new WebViewClient() {
181+
@Override
182+
public boolean shouldOverrideUrlLoading(WebView view, String url) {
183+
view.loadUrl(url);
184+
return false;
185+
}
186+
});
187+
mLayout = new AbsoluteLayout(PythonActivity.mActivity);
188+
mLayout.addView(mWebView);
185189

186-
setContentView(mLayout);
190+
setContentView(mLayout);
187191

188-
String mFilesDirectory = mActivity.getFilesDir().getAbsolutePath();
189-
String entry_point = getEntryPoint(app_root_dir);
192+
String mFilesDirectory = mActivity.getFilesDir().getAbsolutePath();
193+
String entry_point = getEntryPoint(app_root_dir);
190194

191-
Log.v(TAG, "Setting env vars for start.c and Python to use");
192-
PythonActivity.nativeSetenv("ANDROID_ENTRYPOINT", entry_point);
193-
PythonActivity.nativeSetenv("ANDROID_ARGUMENT", app_root_dir);
194-
PythonActivity.nativeSetenv("ANDROID_APP_PATH", app_root_dir);
195-
PythonActivity.nativeSetenv("ANDROID_PRIVATE", mFilesDirectory);
196-
PythonActivity.nativeSetenv("ANDROID_UNPACK", app_root_dir);
197-
PythonActivity.nativeSetenv("PYTHONHOME", app_root_dir);
198-
PythonActivity.nativeSetenv("PYTHONPATH", app_root_dir + ":" + app_root_dir + "/lib");
199-
PythonActivity.nativeSetenv("PYTHONOPTIMIZE", "2");
195+
Log.v(TAG, "Setting env vars for start.c and Python to use");
196+
PythonActivity.nativeSetenv("ANDROID_ENTRYPOINT", entry_point);
197+
PythonActivity.nativeSetenv("ANDROID_ARGUMENT", app_root_dir);
198+
PythonActivity.nativeSetenv("ANDROID_APP_PATH", app_root_dir);
199+
PythonActivity.nativeSetenv("ANDROID_PRIVATE", mFilesDirectory);
200+
PythonActivity.nativeSetenv("ANDROID_UNPACK", app_root_dir);
201+
PythonActivity.nativeSetenv("PYTHONHOME", app_root_dir);
202+
PythonActivity.nativeSetenv("PYTHONPATH", app_root_dir + ":" + app_root_dir + "/lib");
203+
PythonActivity.nativeSetenv("PYTHONOPTIMIZE", "2");
200204

201-
try {
202-
Log.v(TAG, "Access to our meta-data...");
203-
mActivity.mMetaData = mActivity.getPackageManager().getApplicationInfo(
204-
mActivity.getPackageName(), PackageManager.GET_META_DATA).metaData;
205-
206-
PowerManager pm = (PowerManager) mActivity.getSystemService(Context.POWER_SERVICE);
207-
if ( mActivity.mMetaData.getInt("wakelock") == 1 ) {
208-
mActivity.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "Screen On");
209-
mActivity.mWakeLock.acquire();
205+
try {
206+
Log.v(TAG, "Access to our meta-data...");
207+
mActivity.mMetaData = mActivity.getPackageManager().getApplicationInfo(
208+
mActivity.getPackageName(), PackageManager.GET_META_DATA).metaData;
209+
210+
PowerManager pm = (PowerManager) mActivity.getSystemService(Context.POWER_SERVICE);
211+
if ( mActivity.mMetaData.getInt("wakelock") == 1 ) {
212+
mActivity.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "Screen On");
213+
mActivity.mWakeLock.acquire();
214+
}
215+
} catch (PackageManager.NameNotFoundException e) {
210216
}
211-
} catch (PackageManager.NameNotFoundException e) {
212-
}
213-
214-
final Thread pythonThread = new Thread(new PythonMain(), "PythonThread");
215-
PythonActivity.mPythonThread = pythonThread;
216-
pythonThread.start();
217217

218-
final Thread wvThread = new Thread(new WebViewLoaderMain(), "WvThread");
219-
wvThread.start();
218+
final Thread pythonThread = new Thread(new PythonMain(), "PythonThread");
219+
PythonActivity.mPythonThread = pythonThread;
220+
pythonThread.start();
220221

222+
final Thread wvThread = new Thread(new WebViewLoaderMain(), "WvThread");
223+
wvThread.start();
224+
}
221225
}
222226

223227
@Override
@@ -367,6 +371,73 @@ public boolean onKeyDown(int keyCode, KeyEvent event) {
367371
return super.onKeyDown(keyCode, event);
368372
}
369373

374+
// loading screen implementation
375+
public static ImageView mImageView = null;
376+
public void removeLoadingScreen() {
377+
runOnUiThread(new Runnable() {
378+
public void run() {
379+
if (PythonActivity.mImageView != null &&
380+
PythonActivity.mImageView.getParent() != null) {
381+
((ViewGroup)PythonActivity.mImageView.getParent()).removeView(
382+
PythonActivity.mImageView);
383+
PythonActivity.mImageView = null;
384+
}
385+
}
386+
});
387+
}
388+
389+
protected void showLoadingScreen() {
390+
// load the bitmap
391+
// 1. if the image is valid and we don't have layout yet, assign this bitmap
392+
// as main view.
393+
// 2. if we have a layout, just set it in the layout.
394+
// 3. If we have an mImageView already, then do nothing because it will have
395+
// already been made the content view or added to the layout.
396+
397+
if (mImageView == null) {
398+
int presplashId = this.resourceManager.getIdentifier("presplash", "drawable");
399+
InputStream is = this.getResources().openRawResource(presplashId);
400+
Bitmap bitmap = null;
401+
try {
402+
bitmap = BitmapFactory.decodeStream(is);
403+
} finally {
404+
try {
405+
is.close();
406+
} catch (IOException e) {};
407+
}
408+
409+
mImageView = new ImageView(this);
410+
mImageView.setImageBitmap(bitmap);
411+
412+
/*
413+
* Set the presplash loading screen background color
414+
* https://developer.android.com/reference/android/graphics/Color.html
415+
* Parse the color string, and return the corresponding color-int.
416+
* If the string cannot be parsed, throws an IllegalArgumentException exception.
417+
* Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
418+
* 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta', 'yellow',
419+
* 'lightgray', 'darkgray', 'grey', 'lightgrey', 'darkgrey', 'aqua', 'fuchsia',
420+
* 'lime', 'maroon', 'navy', 'olive', 'purple', 'silver', 'teal'.
421+
*/
422+
String backgroundColor = resourceManager.getString("presplash_color");
423+
if (backgroundColor != null) {
424+
try {
425+
mImageView.setBackgroundColor(Color.parseColor(backgroundColor));
426+
} catch (IllegalArgumentException e) {}
427+
}
428+
mImageView.setLayoutParams(new ViewGroup.LayoutParams(
429+
ViewGroup.LayoutParams.FILL_PARENT,
430+
ViewGroup.LayoutParams.FILL_PARENT));
431+
mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
432+
433+
}
434+
435+
if (mLayout == null) {
436+
setContentView(mImageView);
437+
} else if (PythonActivity.mImageView.getParent() == null){
438+
mLayout.addView(mImageView);
439+
}
440+
}
370441

371442
//----------------------------------------------------------------------------
372443
// Listener interface for onNewIntent

0 commit comments

Comments
 (0)