原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://mikewang.blog.51cto.com/3826268/1206701
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/**
* Saves the view data to the output stream. The output is highly
* version specific, and may not be able to be loaded by newer versions
* of WebView.
* @param stream The {@link OutputStream} to save to
* @return True if saved successfully
* @hide
*/
public
boolean
saveViewState(OutputStream stream) {
try
{
return
ViewStateSerializer.serializeViewState(stream,
this
);
}
catch
(IOException e) {
Log.w(LOGTAG,
"Failed to saveViewState"
, e);
}
return
false
;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/**
* Saves the view data to the output stream. The output is highly
* version specific, and may not be able to be loaded by newer versions
* of WebView.
* @param stream The {@link OutputStream} to save to
* @param callback The {@link ValueCallback} to call with the result
*/
public
void
saveViewState(OutputStream stream, ValueCallback<Boolean> callback) {
if
(mWebViewCore ==
null
) {
callback.onReceiveValue(
false
);
return
;
}
mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SAVE_VIEW_STATE,
new
WebViewCore.SaveViewStateRequest(stream, callback));
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public
boolean
mySaveViewState(OutputStream stream) {
boolean
ret =
false
;
if
(mMethodSaveViewState ==
null
)
try
{
mMethodSaveViewState = WebView.
class
.getDeclaredMethod(
"saveViewState"
, OutputStream.
class
);
mMethodSaveViewState.setAccessible(
true
);
}
catch
(NoSuchMethodException e) {
}
if
(mMethodSaveViewState !=
null
) {
try
{
ret = (Boolean) mMethodSaveViewState.invoke(
this
, stream);
}
catch
(IllegalArgumentException e) {
e.printStackTrace();
}
catch
(IllegalAccessException e) {
e.printStackTrace();
}
catch
(InvocationTargetException e) {
e.printStackTrace();
}
}
return
ret;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/**
* Save the state of this WebView used in
* {@link android.app.Activity#onSaveInstanceState}. Please note that this
* method no longer stores the display data for this WebView. The previous
* behavior could potentially leak files if {@link #restoreState} was never
* called. See {@link #savePicture} and {@link #restorePicture} for saving
* and restoring the display data.
* @param outState The Bundle to store the WebView state.
* @return The same copy of the back/forward list used to save the state. If
* saveState fails, the returned list will be null.
* @see #savePicture
* @see #restorePicture
*/
public
WebBackForwardList saveState(Bundle outState) {
if
(outState ==
null
) {
return
null
;
}
// We grab a copy of the back/forward list because a client of WebView
// may have invalidated the history list by calling clearHistory.
WebBackForwardList list = copyBackForwardList();
final
int
currentIndex = list.getCurrentIndex();
final
int
size = list.getSize();
// We should fail saving the state if the list is empty or the index is
// not in a valid range.
if
(currentIndex <
0
|| currentIndex >= size || size ==
0
) {
return
null
;
}
outState.putInt(
"index"
, currentIndex);
// FIXME: This should just be a byte[][] instead of ArrayList but
// Parcel.java does not have the code to handle multi-dimensional
// arrays.
ArrayList<
byte
[]> history =
new
ArrayList<
byte
[]>(size);
for
(
int
i =
0
; i < size; i++) {
WebHistoryItem item = list.getItemAtIndex(i);
if
(
null
== item) {
// FIXME: this shouldn't happen
// need to determine how item got set to null
Log.w(LOGTAG,
"saveState: Unexpected null history item."
);
return
null
;
}
byte
[] data = item.getFlattenedData();
if
(data ==
null
) {
// It would be very odd to not have any data for a given history
// item. And we will fail to rebuild the history list without
// flattened data.
return
null
;
}
history.add(data);
}
outState.putSerializable(
"history"
, history);
if
(mCertificate !=
null
) {
outState.putBundle(
"certificate"
,
SslCertificate.saveState(mCertificate));
}
return
list;
}
/**
* Save the current display data to the Bundle given. Used in conjunction
* with {@link #saveState}.
* @param b A Bundle to store the display data.
* @param dest The file to store the serialized picture data. Will be
* overwritten with this WebView's picture data.
* @return True if the picture was successfully saved.
*/
public
boolean
savePicture(Bundle b,
final
File dest) {
if
(dest ==
null
|| b ==
null
) {
return
false
;
}
final
Picture p = capturePicture();
// Use a temporary file while writing to ensure the destination file
// contains valid data.
final
File temp =
new
File(dest.getPath() +
".writing"
);
new
Thread(
new
Runnable() {
public
void
run() {
FileOutputStream out =
null
;
try
{
out =
new
FileOutputStream(temp);
p.writeToStream(out);
// Writing the picture succeeded, rename the temporary file
// to the destination.
temp.renameTo(dest);
}
catch
(Exception e) {
// too late to do anything about it.
}
finally
{
if
(out !=
null
) {
try
{
out.close();
}
catch
(Exception e) {
// Can't do anything about that
}
}
temp.delete();
}
}
}).start();
// now update the bundle
b.putInt(
"scrollX"
, mScrollX);
b.putInt(
"scrollY"
, mScrollY);
b.putFloat(
"scale"
, mActualScale);
b.putFloat(
"textwrapScale"
, mTextWrapScale);
b.putBoolean(
"overview"
, mInZoomOverview);
return
true
;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/**
* Return a new picture that captures the current display of the webview.
* This is a copy of the display, and will be unaffected if the webview
* later loads a different URL.
*
* @return a picture containing the current contents of the view. Note this
* picture is of the entire document, and is not restricted to the
* bounds of the view.
*/
public
Picture capturePicture() {
if
(
null
== mWebViewCore)
return
null
;
// check for out of memory tab
return
mWebViewCore.copyContentPicture();
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
//FIXME draw on canvas can not run in a non-ui thread
boolean
saveAsPng(Context ctx, ContentValues values, Picture picture){
String path = UUID.randomUUID().toString();
OutputStream outs =
null
;
try
{
if
(
null
== picture)
return
false
;
String png = path +
".png"
;
outs = ctx.openFileOutput(png, Context.MODE_PRIVATE);
PictureDrawable pictureDrawable =
new
PictureDrawable(
picture);
Bitmap bitmap =
null
;
bitmap = Bitmap.createBitmap(
pictureDrawable.getIntrinsicWidth(),
pictureDrawable.getIntrinsicHeight(),
Config.ARGB_8888);
Canvas canvas =
new
Canvas(bitmap);
canvas.drawPicture(pictureDrawable.getPicture());
bitmap.compress(Bitmap.CompressFormat.PNG,
100
, outs);
outs.flush();
outs.close();
bitmap.recycle();
bitmap =
null
;
values.put(SavedPageColumns.TYPE, SavedPage.TYPE_PNG);
values.put(SavedPageColumns.PATH, png);
}
catch
(Exception e) {
Log.w(LOGTAG,
"Failed to save page "
, e);
if
(outs !=
null
) {
try
{
outs.close();
}
catch
(IOException ignore) {
}
}
File file = ctx.getFileStreamPath(path);
if
(file !=
null
&& file.exists() && !file.delete()) {
file.deleteOnExit();
}
return
false
;
}
return
true
;
}
|