Android: Hoe doen 'n vertoning 'n groot geanimeerde gif gegee 'n url?
-
03-07-2019 - |
Vra
As ek die URL vir groot geanimeerde gif en ek wou 'n youtube soos aktiwiteit wat die animasie in 'n streaming manier vertoon maak. Hoe doen ek
- stroom in die beeld?
- kry dit vertoon doen met werklike animasie?
Ek weet ImageView
is nie die antwoord as dit wys net die eerste raam.
'n bonus sal toegang tot sy buffer status sodat ek kan sinchroniseer stroom klank sowel - dit is deel van 'n YTMND 'n> kyker aansoek. Terwyl ek 'n diens wat die openbare gif lêers transform coderen in 'n mooier formaat kan skep, sou ek die jeug om te funksioneer sonder bykomende afhanklikhede hou.
Oplossing
Die algemene skets van die oplossing is om diens persoonlike View
wat trek vra 'n Movie
om homself van tyd tot tyd te vestig op die Canvas
gebruik.
Die eerste stap is die bou van die Movie
byvoorbeeld. Daar is fabriek genoem decodeStream
dat 'n fliek gegee 'n InputStream
kan maak, maar dit is nie genoeg om die stroom te gebruik van 'n UrlConnection
. As jy dit probeer sal jy 'n IOException
kry wanneer die film loader probeer reset
'n beroep op die stroom. Die hack, jammer want dit is, is om 'n geskei BufferedInputStream
gebruik met 'n hand-stel mark
om dit te vertel om genoeg data wat reset
sal nie dof brand te red. Gelukkig kan die URLConnection
ons vertel hoeveel data om te verwag. Ek sê dit hack is jammer, want dit effektief vereis dat die hele beeld te gebuffer in geheue (dit is nie 'n probleem vir die lessenaar programme, maar dit is 'n ernstige saak op 'n geheue beperk mobiele toestel).
Hier is 'n snip van die Movie
opstel kode:
URL url = new URL(gifSource);
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bis.mark(conn.getContentLength());
Movie movie = Movie.decodeStream(bis);
bis.close();
Volgende, moet jy 'n siening dat hierdie Movie
sal vertoon te skep. A subklas van View
met 'n persoonlike onDraw
sal die truuk doen (die veronderstelling dat dit toegang tot die Movie
jy geskep met die vorige kode het).
@Override protected void onDraw(Canvas canvas) {
if(movie != null) {
long now = android.os.SystemClock.uptimeMillis();
int dur = Math.max(movie.duration(), 1); // is it really animated?
int pos = (int)(now % dur);
movie.setTime(pos);
movie.draw(canvas, x, y);
}
}
Die vertoning sal self nie die sneller te teruggeteken sonder hulp, en blindelings roeping invalidate()
aan die einde van onDraw
is net 'n energie-afval. In 'n ander draad (waarskynlik die een wat jy gebruik om die beeld data te laai), kan jy boodskappe stuur na die hoof draad, vra vir die oog op ongeldig teen 'n bestendige (maar nie mal) pas.
Handler handler = new Handler();
new Thread() {
@Override public void run() {
// ... setup the movie (using the code from above)
// ... create and display the custom view, passing the movie
while(!Thread.currentThread().isInterrupted()) {
handler.post(new Runnable() {
public void run(){
view.invalidate();
}
});
try {
Thread.sleep(50); // yields 20 fps
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}.start();
'n baie mooi oplossing sou allerhande soet vordering bars en foutopsporing het, maar die kern is hier.
Ander wenke
Het jy probeer BitmapDecode
?
Daar is 'n voorbeeld in die API Demos hier .
gly bewys mees maklik en doeltreffende manier om dit reg te kry met net een lyn van kode: -
Glide.with(getApplicationContext())
.load(Uri.parse("https://media1.giphy.com/media/5ziaphcUWGKPu/200.gif"))
.asGif().placeholder(R.drawable.ic_launcher).crossFade()
.into(imageView);
Die resultaat is hier: -
Gif geneem uit hier http://giphy.com/search/big-gif/3
jar Voeg uit hier: - https://github.com/bumptech/glide/releases'n>
Miskien AnimationDrawable kan vir jou werk? EDIT: Nie as jy wil om te laai van 'n URL soos hierdie post is oor. Jammer
http://developer.android.com/reference/android/ grafiese / tekenbaar / AnimationDrawable.html
Na gelang van die kompleksiteit van die GIF maw as dit is 'n eenvoudige laai / vordering aanwyser jy kan die GIF breek, spaar elke beeld afsonderlik en gebruik die Android Raamwerk se AnimationDrawable.
Vir eenvoudige vordering bars dit kan minder gevoelig vir foute, miskien selfs meer performante wees.