二进制 XML 文件第 13 行:在扩展 VideoView 的类上膨胀类时出错
Posted
技术标签:
【中文标题】二进制 XML 文件第 13 行:在扩展 VideoView 的类上膨胀类时出错【英文标题】:Binary XML file line #13: Error inflating class on a class that extends VideoView 【发布时间】:2016-02-14 22:47:23 【问题描述】:我创建了一个自定义 VideoView 类,它扩展了 VideoView 并声明了三个构造函数:
package com.tibo.webtv;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import org.apache.http.conn.ConnectTimeoutException;
import com.framework.utilityframe.log.log;
import com.framework.utilityframe.utility.utility;
import com.tibo.webtv.activities.PlayerActivity;
import com.tibo.webtv.database.objects.ServerResponseObject;
import com.tibo.webtv.database.objects.TVChannelObject;
import com.tibo.webtv.global.Global;
import com.tibo.webtv.util.TiboCacheKey;
import com.tibo.webtv.util.Util;
import com.tibo.webtv.web.TiboLog;
import com.tibo.webtv.web.WebHelper3;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.Toast;
import android.widget.VideoView;
public class CustomVideoView extends VideoView implements OnPreparedListener,OnErrorListener,OnInfoListener,OnCompletionListener
private long buffer_start_time;
private long buffer_end_time;
private String token;
private Handler handler = new Handler();
public CustomVideoView(Context context)
super(context);
public CustomVideoView(Context context, AttributeSet attrs)
super(context, attrs);
setOnPreparedListener(this);
setOnErrorListener(this);
setOnInfoListener(this);
public CustomVideoView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
public TVChannelObject getCurrentPlayingChannel()
return current_playing_channel;
public void setCurrentPlayingChannel(TVChannelObject current_playing_channel)
this.current_playing_channel = current_playing_channel;
public TVChannelObject getPreviousPlayingChannel()
return previous_playing_channel;
public void setPreviousPlayingChannel(TVChannelObject previous_playing_channel)
this.previous_playing_channel = previous_playing_channel;
private TVChannelObject current_playing_channel;
private TVChannelObject previous_playing_channel;
private String access_way;
private Date stream_started_time;
private long stream_play_time;
private boolean FLAG_STREAM_STARTED;
private String error_code;
@Override
public void stopPlayback()
new WatchingTime().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
super.stopPlayback();
@Override
public void onPrepared(MediaPlayer mp)
log.i("on Prepared");
FLAG_STREAM_STARTED = true;
stream_started_time = Calendar.getInstance().getTime();
mp.start();
@Override
public boolean onError(MediaPlayer mp, int what, int extra)
log.i("on onError");
error_code = what + "";
Toast.makeText(getContext(),getContext().getString(R.string.videoerror) + " " + error_code, Toast.LENGTH_LONG).show();
new BlackScreenError().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
if(what == MediaPlayer.MEDIA_ERROR_SERVER_DIED)
mp.reset();
else if(what == MediaPlayer.MEDIA_ERROR_UNKNOWN)
mp.reset();
return true;
;
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra)
log.i("on onInfo");
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START)
buffer_start_time = System.currentTimeMillis();
else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END)
buffer_end_time = System.currentTimeMillis();
new Buffering_Problem().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
FLAG_STREAM_STARTED = false;
return true;
@Override
public void onCompletion(MediaPlayer mp)
super.setOnCompletionListener(this);
new WatchingTime().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
public void start(TVChannelObject channel)
super.start();
if(current_playing_channel == null)
current_playing_channel = channel;
else
previous_playing_channel = current_playing_channel;
current_playing_channel = channel;
Global.shared_preference.setValue(TiboCacheKey.PLAYING_CHANNEL, current_playing_channel.number);
Global.shared_preference.setValue(TiboCacheKey.LAST_CHANNEL_VIEWED, previous_playing_channel.number);
this.access_way = "-1";
public synchronized void start(TVChannelObject channel,String access_way)
super.start();
if(isPlaying())
this.stopPlayback();
if(current_playing_channel == null)
current_playing_channel = channel;
else
previous_playing_channel = current_playing_channel;
current_playing_channel = channel;
Global.shared_preference.setValue(TiboCacheKey.PLAYING_CHANNEL, current_playing_channel.number);
if(!utility.stringCompareIgnoreCase(current_playing_channel.videotype, "2"))
Global.shared_preference.setValue(TiboCacheKey.LAST_CHANNEL_VIEWED, current_playing_channel.number);
this.access_way = access_way;
if (current_playing_channel.token.trim().toLowerCase(Locale.getDefault()).toCharArray()[0] == '1')
log.i("Channel with token!!!");
new PlayStreamWithToken().execute("");
else
log.i("Channel without token!!!");
token = "";
setVideoURI(Uri.parse(current_playing_channel.url));
start();
closePlayerActivityAfterSpecificTime(1000 * 60 * 120);
new ChannelHits().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
private void closePlayerActivityAfterSpecificTime(int milliseconds)
handler.removeCallbacks(ClosePlayerActivity);
handler.postDelayed(ClosePlayerActivity, milliseconds);
private Runnable ClosePlayerActivity = new Runnable()
public void run()
new ClosePlayerActivityAfterInActivity().execute(0);
;
private class PlayStreamWithToken extends AsyncTask<String, String, String>
ServerResponseObject<String> token_response = null;
@Override
protected void onPreExecute()
super.onPreExecute();
@Override
protected String doInBackground(String... params)
Thread.currentThread().setName("get token");
log.i("Channel with token!!!");
log.i("token url",current_playing_channel.TokenUrl);
try
token_response = WebHelper3.getToken(current_playing_channel.TokenUrl);
if(token_response != null)
if(token_response.status_code < 300)
if(!utility.stringCompareIgnoreCase(token_response.extra_data, ""))
token = token_response.extra_data;
log.i("token",token);
return Util.RESPONSE_OK;
else
//TODO handle error
return Util.RESPONSE_ERROR;
else
//TODO hanlde
token = "";
return Util.RESPONSE_NULL;
catch (ConnectTimeoutException e)
// TODO Auto-generated catch block
e.printStackTrace();
return Util.RESPONSE_TIME_OUT;
return "";
protected void onPostExecute(String response)
if(utility.stringCompareIgnoreCase(response, Util.RESPONSE_OK))
String channel_url_to_play = current_playing_channel.url;
channel_url_to_play += token.trim();
log.i("url to play with token :", channel_url_to_play);
setVideoURI(Uri.parse(channel_url_to_play));
start();
closePlayerActivityAfterSpecificTime(1000 * 60 * 120);
else if(utility.stringCompareIgnoreCase(response, Util.RESPONSE_TIME_OUT))
//TODO handle timout and null
private class ClosePlayerActivityAfterInActivity extends AsyncTask<Integer, Integer, Integer>
@Override
protected Integer doInBackground(Integer... params)
Thread.currentThread().setName("SleepTask");
return 0;
@Override
protected void onPostExecute(Integer result)
if (isPlaying())
stopPlayback();
PlayerActivity.this_activity.finish();
private class Buffering_Problem extends AsyncTask<Integer, Integer, Integer>
@Override
protected void onPreExecute()
super.onPreExecute();
@Override
protected Integer doInBackground(Integer... params)
Thread.currentThread().setName("Buffering problem Custom VideoView");
if (FLAG_STREAM_STARTED)
TiboLog.logBufferingError(TiboLog.LIVE_TV_BUFFER_ERRORS,current_playing_channel.number, buffer_end_time - buffer_start_time, "Warning");
else
TiboLog.logBufferingError(TiboLog.LIVE_TV_BUFFER_ERRORS,current_playing_channel.number, buffer_end_time - buffer_start_time, "Error");
buffer_end_time = 0;
buffer_start_time = 0;
return 0;
private class BlackScreenError extends AsyncTask<Integer, Integer, Integer>
@Override
protected void onPreExecute()
super.onPreExecute();
@Override
protected Integer doInBackground(Integer... params)
Thread.currentThread().setName("Black Screen Error");
try
TiboLog.logSendError(TiboLog.LOGTYPE_ERROR,current_playing_channel.number, "Error Black Screen " + error_code);
catch (Exception e)
e.printStackTrace();
return 0;
private class ChannelHits extends AsyncTask<Integer, Integer, Integer>
@Override
protected void onPreExecute()
super.onPreExecute();
@Override
protected Integer doInBackground(Integer... params)
Thread.currentThread().setName("Channel Hit log");
TiboLog.logChannelHit(TiboLog.LIVE_TV_HITS,current_playing_channel.number, access_way, previous_playing_channel.number);
return 0;
private class WatchingTime extends AsyncTask<Integer, Integer, Integer>
@Override
protected void onPreExecute()
super.onPreExecute();
@Override
protected Integer doInBackground(Integer... params)
Thread.currentThread().setName("Watching Time Log");
if(stream_started_time != null)
long stream_ended_time = Calendar.getInstance().getTime().getTime();
stream_play_time = stream_ended_time - stream_started_time.getTime();
int playtime_in_seconds = (int) (stream_play_time)/1000;
log.i("playtime_in_seconds",playtime_in_seconds+"");
if (playtime_in_seconds >= 15 && playtime_in_seconds < 108000)
TiboLog.sendWatchingTime(TiboLog.LIVE_TV_WATCHING_TIME, current_playing_channel.number, playtime_in_seconds + "");
return 0;
xml文件如下:
<RelativeLayout
android:id="@+id/media_player_view"
android:layout_
android:layout_ >
<com.tibo.webtv.CustomVideoView --line 13
android:id="@+id/surface_view"
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_gravity="center" />
</RelativeLayout>
当我在 android 4.1 上运行这个 apk 时,活动崩溃并且日志消息是:
11-13 11:36:27.962: E/AndroidRuntime(1040): FATAL EXCEPTION: main
11-13 11:36:27.962: E/AndroidRuntime(1040): java.lang.RuntimeException: Unable to start activity ComponentInfocom.tibo.webtv/com.tibo.webtv.activities.PlayerActivity: android.view.InflateException: Binary XML file line #13: Error inflating class com.webtv.CustomVideoView
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.app.ActivityThread.access$600(ActivityThread.java:130)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.os.Handler.dispatchMessage(Handler.java:99)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.os.Looper.loop(Looper.java:137)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.app.ActivityThread.main(ActivityThread.java:4745)
11-13 11:36:27.962: E/AndroidRuntime(1040): at java.lang.reflect.Method.invokeNative(Native Method)
11-13 11:36:27.962: E/AndroidRuntime(1040): at java.lang.reflect.Method.invoke(Method.java:511)
11-13 11:36:27.962: E/AndroidRuntime(1040): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
11-13 11:36:27.962: E/AndroidRuntime(1040): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-13 11:36:27.962: E/AndroidRuntime(1040): at dalvik.system.NativeStart.main(Native Method)
11-13 11:36:27.962: E/AndroidRuntime(1040): Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class com.webtv.CustomVideoView
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:698)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
11-13 11:36:27.962: E/AndroidRuntime(1040): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:256)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.app.Activity.setContentView(Activity.java:1867)
11-13 11:36:27.962: E/AndroidRuntime(1040): at com.tibo.webtv.activities.PlayerActivity.onCreate(PlayerActivity.java:188)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.app.Activity.performCreate(Activity.java:5008)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
11-13 11:36:27.962: E/AndroidRuntime(1040): ... 11 more
11-13 11:36:27.962: E/AndroidRuntime(1040): Caused by: java.lang.ClassNotFoundException: com.webtv.CustomVideoView
11-13 11:36:27.962: E/AndroidRuntime(1040): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
11-13 11:36:27.962: E/AndroidRuntime(1040): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
11-13 11:36:27.962: E/AndroidRuntime(1040): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.view.LayoutInflater.createView(LayoutInflater.java:552)
11-13 11:36:27.962: E/AndroidRuntime(1040): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
11-13 11:36:27.962: E/AndroidRuntime(1040): ... 22 more
我猜问题出在 OnInfoListener 上,因为当我删除它时一切正常。
【问题讨论】:
请发布完整的堆栈跟踪和CustomVideoView
类。
@MikeM。我更新了我的问题
ClassNotFoundException: com.webtv.CustomVideoView
。你确定它不应该是com.tibo.webtv.CustomVideoView
?
我用xxxx隐藏包名
是的,我收集到了,但你的堆栈跟踪显示com.webtv.CustomVideoView
。如果您最近更改了它(清理并)重建您的项目。
【参考方案1】:
问题在于包名。将您在 xml 中使用的完整限定类名称与您的类定义进行交叉检查。
简而言之,当您按下 ctrl+鼠标左键时,您应该被重定向到类定义。
应该是com.packagename.yourCustomclassName
【讨论】:
当我按下 CTRL+鼠标左键时,它会将我重定向到类定义,所以包名是正确的【参考方案2】:就我而言,我已经删除了该属性 android:background,从那时起我没有收到任何 inflate 异常。
【讨论】:
以上是关于二进制 XML 文件第 13 行:在扩展 VideoView 的类上膨胀类时出错的主要内容,如果未能解决你的问题,请参考以下文章
无法启动活动 ComponentInfo 二进制 XML 文件第 13 行:膨胀类 com.google.android.material.appbar.MaterialToolbar 时出错
获取二进制 XML 文件第 141 行:尝试在空对象引用上调用虚拟方法“boolean java.lang.String.equals(java.lang.Object)”
二进制 XML 文件第 28 行:二进制 XML 文件第 28 行:膨胀类 <unknown> 时出错
android.view.InflateException:二进制 XML 文件第 15 行:二进制 XML 文件第 19 行:膨胀类片段时出错
Google Map API 问题:android.view.InflateException:二进制 XML 文件第 2 行:二进制 XML 文件第 2 行:膨胀类片段时出错
当我切换到包含片段的活动时应用程序崩溃(二进制 XML 文件第 10 行:二进制 XML 文件第 10 行:膨胀类片段时出错)