问:
ExoPlayer - Cannot catch BehindLiveWindowException
I am using exoplayer in order to play HLS video in my app. The problem is that I am getting BehindLiveWindowException and I have found a solution to reinitialize player if that exception occur. But somehow I cannot catch that exception in my class so I can reinitialize the player.

Instead, I can see BLWE exception in logcat, but restarting the player never occurs.

Please can somebody tell me what am I doing wrong, my code snippet is here:

```<code>public class MainViewModel extends BaseObservable implements ExoPlayer.EventListener {

private static final String MAIN_VIEWMODEL_TAG = "MAIN_VIEWMODEL";
private static MainViewModel mainViewModel;
private final Context context;
private final Realm realm;
private LinearLayoutManager mLinearLayoutManager;
private List<ChannelRCV> channelRCVList;
private ChannelRecyclerViewAdapter recyclerViewAdapter;
private ChannelRCV currentChannelRCV;
private SimpleExoPlayer player;
private Handler mainHandler;
private BandwidthMeter bandwidthMeter;
private TrackSelection.Factory videoTrackSelectionFactory;
private TrackSelector trackSelector;
private LoadControl loadControl;
private DataSource.Factory dataSourceFactory;
private MediaSource videoSource;
private PlayerHelper playerHelper;

//TODO CONSTRUCTOR MainViewModel
private MainViewModel(Context context) {
    this.context = context;
    recyclerViewAdapter = new ChannelRecyclerViewAdapter();

    //channelRCVList = convertList(dbHelper.getWebTvChannelDao().loadAll());
    //currentChannelRCV = channelRCVList.get(0);

    realm = Realm.getDefaultInstance();

    //Log.i(MAIN_VIEWMODEL_TAG, "DB IS EMPTY: "+ realm.isEmpty());
    channelRCVList = Converter.convertList(realm.where(WebTvChannel.class).findAll());

    ForTest forTest = new ForTest();

    forTest.test1();

    Log.i(MAIN_VIEWMODEL_TAG, channelRCVList.size() + "");
    currentChannelRCV = channelRCVList.get(0);
    recyclerViewAdapter.setList(channelRCVList);
    recyclerViewAdapter.notifyDataSetChanged();
    downloadEpgScheduler();

}

public static MainViewModel getInstance(Context context) {

    if (mainViewModel == null) {
        mainViewModel = new MainViewModel(context);
        mainViewModel.setupPlayer();
        return mainViewModel;
    } else
        return mainViewModel;
}

private static boolean isBehindLiveWindow(ExoPlaybackException e) {
    if (e.type != ExoPlaybackException.TYPE_SOURCE) {
        return false;
    }
    Throwable cause = e.getSourceException();
    while (cause != null) {
        if (cause instanceof BehindLiveWindowException) {
            return true;
        }
        cause = cause.getCause();
    }
    return false;
}

private List<ChannelRCV> convertList(List<WebTvChannel> webTvChannels) {
    List<ChannelRCV> channelRCVs = new ArrayList<>();
    for (WebTvChannel ch : webTvChannels) {
        channelRCVs.add(new ChannelRCV(ch.getName(), ch.getUrl()));
    }

    return channelRCVs;
}

@Bindable
public SimpleExoPlayer getPlayer() {
    return player;
}

public void setPlayer(SimpleExoPlayer player) {

    this.player = player;

    notifyPropertyChanged(BR.player);
}

public void setupPlayer() {
    //System.out.println(player);
    if (player != null) {

        //player.clearVideoSurface();

        player.release();

    }

    mainHandler = new Handler();
    bandwidthMeter = new DefaultBandwidthMeter();

    videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    loadControl = new DefaultLoadControl();

    player = ExoPlayerFactory.newSimpleInstance(context, trackSelector, loadControl, null, SimpleExoPlayer.STATE_BUFFERING);

    DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
    dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, "AOC"), defaultBandwidthMeter);
    videoSource = new HlsMediaSource(Uri.parse(currentChannelRCV.getUrl()), dataSourceFactory, mainHandler, new AdaptiveMediaSourceEventListener() {
        @Override
        public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG,"onLoadStarted");
        }

        @Override
        public void onLoadCompleted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
            Log.i(MAIN_VIEWMODEL_TAG,"onLoadCompleted");
        }

        @Override
        public void onLoadCanceled(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
            Log.i(MAIN_VIEWMODEL_TAG, "onLoadCanceled");
        }

        @Override
        public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) {
            Log.i(MAIN_VIEWMODEL_TAG, "onLoadError2");
            player.release();
            setupPlayer();
        }

        @Override
        public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG, "onUpstreamDiscarded");
        }

        @Override
        public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG, "onDownstreamFormatChanged");
        }

    });

    player.prepare(videoSource);

    player.setPlayWhenReady(true);

    setPlayer(player);

}

public void changeChannel(ChannelRCV channelRCV) {

    if (channelRCV.getUrl() == null) {
        Toast.makeText(context, "No resoureces for this channel", Toast.LENGTH_SHORT).show();
        return;
    }

    videoSource = new HlsMediaSource(Uri.parse(currentChannelRCV.getUrl()), dataSourceFactory, mainHandler, new AdaptiveMediaSourceEventListener() {
        @Override
        public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG,"onLoadStarted");
        }

        @Override
        public void onLoadCompleted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
            Log.i(MAIN_VIEWMODEL_TAG,"onLoadCompleted");
        }

        @Override
        public void onLoadCanceled(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
            Log.i(MAIN_VIEWMODEL_TAG, "onLoadCanceled");
        }

        @Override
        public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) {
            setupPlayer();
            Log.e("onLoadError", "ERROR 1");
            Log.e("onLoadError", error.toString());
            Log.i(MAIN_VIEWMODEL_TAG, "onLoadError1");

        }

        @Override
        public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG, "onDownstreamFormatChanged");

        }

        @Override
        public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG, "onDownstreamFormatChanged");
        }

    });
    player.prepare(videoSource);
    player.setPlayWhenReady(true);
    setPlayer(player);

}

public ChannelRecyclerViewAdapter getRecyclerViewAdapter() {
    return recyclerViewAdapter;
}

public LinearLayoutManager getLinearLayoutManager() {

    mLinearLayoutManager = new LinearLayoutManager(context);
    mLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    mLinearLayoutManager.setSmoothScrollbarEnabled(true);
    return mLinearLayoutManager;
}

public int fullscreen() {
    return WindowManager.LayoutParams.FLAG_FULLSCREEN;
}

public void onClick(View view, ChannelRCV channelRCV) {
    //view.setBackgroundColor(Color.parseColor("#FFFFFF"));
    currentChannelRCV = channelRCV;
    changeChannel(channelRCV);
}

// TODO Scheduler
private void downloadEpgScheduler() {

    ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    scheduler.scheduleAtFixedRate(new Runnable() {
        public void run() {

            //code goes here
            Log.i(MAIN_VIEWMODEL_TAG, "SCHEDULER STARTED");
            Intent download = new Intent(context, ScheduledDownloadEpgService.class);
            download.putExtra("package", "AT - WebTV");
            //
            // context.startService(download);

        }
    }, 0, 5, TimeUnit.MINUTES);
}

private void indirectChannelChange() {
    changeChannel(currentChannelRCV);
}

public void updateRecyclerViewList(List<ChannelRCV> channelRCVs) {

    channelRCVList = channelRCVs;
    recyclerViewAdapter.setList(channelRCVs);
    changeChannel(channelRCVs.get(0));
    recyclerViewAdapter.notifyDataSetChanged();
    player.release();
    setupPlayer();

}

@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
    Log.e("onTimelineChanged", "onTimelineChanged");

}

@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
    Log.e("onTracksChanged", "onTracksChanged");

}

@Override
public void onLoadingChanged(boolean isLoading) {
    Log.i("onLoadingChanged", "Loading Changed");
}

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    Log.i("onPlayerStateChanged", "Player State Changed");
}

@Override
public void onPlayerError(ExoPlaybackException error) {
    //System.out.println("///////////////////////////////////////////////////////////////////// onPlayerError");
    Log.e("OnPlayerError", "Error ExoPlayer");
    if (isBehindLiveWindow(error)) {
        Log.e("OnPlayerError", "starting again");

        player.release();
        setupPlayer();

        //changeChannel(currentChannelRCV);
    }
}

@Override
public void onPositionDiscontinuity() {
    Log.i(MAIN_VIEWMODEL_TAG, "onPositionDiscontinuity");
}

@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
    Log.i("onPlaybackParamChanged", "Player State Changed");
}

public void stopPlayer() {
    player.stop();
    player.release();

}

public void setVodUrl(String url) {

}}
</code>```

Thanks

答:
I have found the solution! Instead to implement ExoPlayer.EventListener  I just added to exoPlayer object listener as following:

```<code>exoPlayer.addListener(new ExoPlayer.EventListener() {
            @Override
            public void onTimelineChanged(Timeline timeline, Object manifest) {

            }

            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

            }

            @Override
            public void onLoadingChanged(boolean isLoading) {

            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {
                Log.e(PLAYER_ACTIVITY_TAG, "SOME ERROR IN PLAYER");
                if (isBehindLiveWindow(error)) {
                    setupPlayer();
                }
            }

            @Override
            public void onPositionDiscontinuity() {

            }

            @Override
            public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

            }
        });
</code>```

and method isBehindLiveWindow

```<code> private static boolean isBehindLiveWindow(ExoPlaybackException e) {
        if (e.type != ExoPlaybackException.TYPE_SOURCE) {
            return false;
        }
        Throwable cause = e.getSourceException();
        while (cause != null) {
            if (cause instanceof BehindLiveWindowException) {
                return true;
            }
            cause = cause.getCause();
        }
        return false;
    }
</code>```

Now if error occurs player will be restarted automatically.

Body:
I am using exoplayer in order to play HLS video in my app. The problem is that I am getting BehindLiveWindowException and I have found a solution to reinitialize player if that exception occur. But somehow I cannot catch that exception in my class so I can reinitialize the player.

Instead, I can see BLWE exception in logcat, but restarting the player never occurs.

Please can somebody tell me what am I doing wrong, my code snippet is here:

public class MainViewModel extends BaseObservable implements ExoPlayer.EventListener {

private static final String MAIN_VIEWMODEL_TAG = "MAIN_VIEWMODEL";
private static MainViewModel mainViewModel;
private final Context context;
private final Realm realm;
private LinearLayoutManager mLinearLayoutManager;
private List<ChannelRCV> channelRCVList;
private ChannelRecyclerViewAdapter recyclerViewAdapter;
private ChannelRCV currentChannelRCV;
private SimpleExoPlayer player;
private Handler mainHandler;
private BandwidthMeter bandwidthMeter;
private TrackSelection.Factory videoTrackSelectionFactory;
private TrackSelector trackSelector;
private LoadControl loadControl;
private DataSource.Factory dataSourceFactory;
private MediaSource videoSource;
private PlayerHelper playerHelper;

//TODO CONSTRUCTOR MainViewModel
private MainViewModel(Context context) {
    this.context = context;
    recyclerViewAdapter = new ChannelRecyclerViewAdapter();

    //channelRCVList = convertList(dbHelper.getWebTvChannelDao().loadAll());
    //currentChannelRCV = channelRCVList.get(0);

    realm = Realm.getDefaultInstance();

    //Log.i(MAIN_VIEWMODEL_TAG, "DB IS EMPTY: "+ realm.isEmpty());
    channelRCVList = Converter.convertList(realm.where(WebTvChannel.class).findAll());

    ForTest forTest = new ForTest();

    forTest.test1();

    Log.i(MAIN_VIEWMODEL_TAG, channelRCVList.size() + "");
    currentChannelRCV = channelRCVList.get(0);
    recyclerViewAdapter.setList(channelRCVList);
    recyclerViewAdapter.notifyDataSetChanged();
    downloadEpgScheduler();

}

public static MainViewModel getInstance(Context context) {

    if (mainViewModel == null) {
        mainViewModel = new MainViewModel(context);
        mainViewModel.setupPlayer();
        return mainViewModel;
    } else
        return mainViewModel;
}

private static boolean isBehindLiveWindow(ExoPlaybackException e) {
    if (e.type != ExoPlaybackException.TYPE_SOURCE) {
        return false;
    }
    Throwable cause = e.getSourceException();
    while (cause != null) {
        if (cause instanceof BehindLiveWindowException) {
            return true;
        }
        cause = cause.getCause();
    }
    return false;
}

private List<ChannelRCV> convertList(List<WebTvChannel> webTvChannels) {
    List<ChannelRCV> channelRCVs = new ArrayList<>();
    for (WebTvChannel ch : webTvChannels) {
        channelRCVs.add(new ChannelRCV(ch.getName(), ch.getUrl()));
    }

    return channelRCVs;
}

@Bindable
public SimpleExoPlayer getPlayer() {
    return player;
}

public void setPlayer(SimpleExoPlayer player) {

    this.player = player;

    notifyPropertyChanged(BR.player);
}

public void setupPlayer() {
    //System.out.println(player);
    if (player != null) {

        //player.clearVideoSurface();

        player.release();

    }

    mainHandler = new Handler();
    bandwidthMeter = new DefaultBandwidthMeter();

    videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    loadControl = new DefaultLoadControl();

    player = ExoPlayerFactory.newSimpleInstance(context, trackSelector, loadControl, null, SimpleExoPlayer.STATE_BUFFERING);

    DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
    dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, "AOC"), defaultBandwidthMeter);
    videoSource = new HlsMediaSource(Uri.parse(currentChannelRCV.getUrl()), dataSourceFactory, mainHandler, new AdaptiveMediaSourceEventListener() {
        @Override
        public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG,"onLoadStarted");
        }

        @Override
        public void onLoadCompleted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
            Log.i(MAIN_VIEWMODEL_TAG,"onLoadCompleted");
        }

        @Override
        public void onLoadCanceled(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
            Log.i(MAIN_VIEWMODEL_TAG, "onLoadCanceled");
        }

        @Override
        public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) {
            Log.i(MAIN_VIEWMODEL_TAG, "onLoadError2");
            player.release();
            setupPlayer();
        }

        @Override
        public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG, "onUpstreamDiscarded");
        }

        @Override
        public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG, "onDownstreamFormatChanged");
        }

    });

    player.prepare(videoSource);

    player.setPlayWhenReady(true);

    setPlayer(player);

}

public void changeChannel(ChannelRCV channelRCV) {

    if (channelRCV.getUrl() == null) {
        Toast.makeText(context, "No resoureces for this channel", Toast.LENGTH_SHORT).show();
        return;
    }

    videoSource = new HlsMediaSource(Uri.parse(currentChannelRCV.getUrl()), dataSourceFactory, mainHandler, new AdaptiveMediaSourceEventListener() {
        @Override
        public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG,"onLoadStarted");
        }

        @Override
        public void onLoadCompleted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
            Log.i(MAIN_VIEWMODEL_TAG,"onLoadCompleted");
        }

        @Override
        public void onLoadCanceled(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
            Log.i(MAIN_VIEWMODEL_TAG, "onLoadCanceled");
        }

        @Override
        public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) {
            setupPlayer();
            Log.e("onLoadError", "ERROR 1");
            Log.e("onLoadError", error.toString());
            Log.i(MAIN_VIEWMODEL_TAG, "onLoadError1");

        }

        @Override
        public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG, "onDownstreamFormatChanged");

        }

        @Override
        public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) {
            Log.i(MAIN_VIEWMODEL_TAG, "onDownstreamFormatChanged");
        }

    });
    player.prepare(videoSource);
    player.setPlayWhenReady(true);
    setPlayer(player);

}

public ChannelRecyclerViewAdapter getRecyclerViewAdapter() {
    return recyclerViewAdapter;
}

public LinearLayoutManager getLinearLayoutManager() {

    mLinearLayoutManager = new LinearLayoutManager(context);
    mLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    mLinearLayoutManager.setSmoothScrollbarEnabled(true);
    return mLinearLayoutManager;
}

public int fullscreen() {
    return WindowManager.LayoutParams.FLAG_FULLSCREEN;
}

public void onClick(View view, ChannelRCV channelRCV) {
    //view.setBackgroundColor(Color.parseColor("#FFFFFF"));
    currentChannelRCV = channelRCV;
    changeChannel(channelRCV);
}

// TODO Scheduler
private void downloadEpgScheduler() {

    ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    scheduler.scheduleAtFixedRate(new Runnable() {
        public void run() {

            //code goes here
            Log.i(MAIN_VIEWMODEL_TAG, "SCHEDULER STARTED");
            Intent download = new Intent(context, ScheduledDownloadEpgService.class);
            download.putExtra("package", "AT - WebTV");
            //
            // context.startService(download);

        }
    }, 0, 5, TimeUnit.MINUTES);
}

private void indirectChannelChange() {
    changeChannel(currentChannelRCV);
}

public void updateRecyclerViewList(List<ChannelRCV> channelRCVs) {

    channelRCVList = channelRCVs;
    recyclerViewAdapter.setList(channelRCVs);
    changeChannel(channelRCVs.get(0));
    recyclerViewAdapter.notifyDataSetChanged();
    player.release();
    setupPlayer();

}

@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
    Log.e("onTimelineChanged", "onTimelineChanged");

}

@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
    Log.e("onTracksChanged", "onTracksChanged");

}

@Override
public void onLoadingChanged(boolean isLoading) {
    Log.i("onLoadingChanged", "Loading Changed");
}

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    Log.i("onPlayerStateChanged", "Player State Changed");
}

@Override
public void onPlayerError(ExoPlaybackException error) {
    //System.out.println("///////////////////////////////////////////////////////////////////// onPlayerError");
    Log.e("OnPlayerError", "Error ExoPlayer");
    if (isBehindLiveWindow(error)) {
        Log.e("OnPlayerError", "starting again");

        player.release();
        setupPlayer();

        //changeChannel(currentChannelRCV);
    }
}

@Override
public void onPositionDiscontinuity() {
    Log.i(MAIN_VIEWMODEL_TAG, "onPositionDiscontinuity");
}

@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
    Log.i("onPlaybackParamChanged", "Player State Changed");
}

public void stopPlayer() {
    player.stop();
    player.release();

}

public void setVodUrl(String url) {

}}

Thanks

Body:
I have found the solution! Instead to implement ExoPlayer.EventListener  I just added to exoPlayer object listener as following:

exoPlayer.addListener(new ExoPlayer.EventListener() {
            @Override
            public void onTimelineChanged(Timeline timeline, Object manifest) {

            }

            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

            }

            @Override
            public void onLoadingChanged(boolean isLoading) {

            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {
                Log.e(PLAYER_ACTIVITY_TAG, "SOME ERROR IN PLAYER");
                if (isBehindLiveWindow(error)) {
                    setupPlayer();
                }
            }

            @Override
            public void onPositionDiscontinuity() {

            }

            @Override
            public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

            }
        });

and method isBehindLiveWindow

 private static boolean isBehindLiveWindow(ExoPlaybackException e) {
        if (e.type != ExoPlaybackException.TYPE_SOURCE) {
            return false;
        }
        Throwable cause = e.getSourceException();
        while (cause != null) {
            if (cause instanceof BehindLiveWindowException) {
                return true;
            }
            cause = cause.getCause();
        }
        return false;
    }

Now if error occurs player will be restarted automatically.


来源: stackexchange

问:
Using jdk with javac instead of ant
I wrote a sample app when trying out java.

calculator/Calc.java

```<code>package calculator;

public abstract class Calc {
    public static float Add(float f1, float f2) {
        return f1 + f2;
    }
    public static float Subtract(float f1, float f2) {
        return f1 - f2;
    }
}
</code>```

Main.java

```<code>import calculator.Calc;

public class Main {
    public static void main (String[] args) {
        System.out.println("1+1=" + Calc.Add(1f, 1f));
        System.out.println("1-0.5=" + Calc.Subtract(1f, 0.5f));
    }
}
</code>```

I managed to compile these classes using jdk into their class files.

Browsing on the web, I found a package called Ant which allows to compile files too. Compiling with Ant also gives me the java class files.

What I want to know is, whats the need for Ant when I can compile my classes directly using jdk without writing any configuration file. Is investing some time into Ant any good when I can build my code using jdk straight away?

答:
Ant is a build automation tool. It can be used to not only compile classes but also run those classes, test those classes,generate javadocs. Mainly used for independent deployment and/or testing of an application.

whats the need for Ant when I can compile my classes directly using
  jdk without writing any configuration file.

Check this out.

Is investing some time into Ant any good when I can build my code
  using jdk straight away?

Depends on what you want to do with our code. Look up Maven and Gradle as well.
Gradle is the newest among them and arguably better as well.

ContentLicense: CC BY-SA 3.0

Title: Using jdk with javac instead of ant

Body:
I wrote a sample app when trying out java.

calculator/Calc.java

package calculator;

public abstract class Calc {
    public static float Add(float f1, float f2) {
        return f1 + f2;
    }
    public static float Subtract(float f1, float f2) {
        return f1 - f2;
    }
}

Main.java

import calculator.Calc;

public class Main {
    public static void main (String[] args) {
        System.out.println("1+1=" + Calc.Add(1f, 1f));
        System.out.println("1-0.5=" + Calc.Subtract(1f, 0.5f));
    }
}

I managed to compile these classes using jdk into their class files.

Browsing on the web, I found a package called Ant which allows to compile files too. Compiling with Ant also gives me the java class files.

What I want to know is, whats the need for Ant when I can compile my classes directly using jdk without writing any configuration file. Is investing some time into Ant any good when I can build my code using jdk straight away?


问:
Is Orchard or Umbraco MVC?
I'm much happier with the quality of output I can get with MVC over webforms: hand crafted HTML that isn't full of additional machine generated gubbins (polite term). I realize of course that MVC is about a lot more than this, but concentrating on just that "view" part...

I'm looking at Orchard or Umbraco for a project. I see both support Razor syntax (Umbraco just about) - but with my strong leaning to MVC Views rather than webforms, does that rule out Umbraco?

All the Umbraco reading I've found so far is about the XSLT engine, as the razor syntax is brand new, which scares me :-)

答:
I've been using Umbraco since version 7.1.4 and I've always used MVC with it.
I know there is still support for web forms too, but its main direction is down the MVC route. The current version as I write this comment is 7.6.3</p>

ContentLicense: CC BY-SA 2.5

Title: Is Orchard or Umbraco MVC?


问:
Is it good that we link dao entity classes with mvc form
I am learning hibernate with spring. While implementing i am creating entity class like below

```<code>@Entity
@Table(name = "USER_DETAILS", uniqueConstraints = @UniqueConstraint(columnNames = "USER_ID"))
public class UserInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "USER_KEY", unique = true, nullable = false)
    private Long userKey;

    @Column(name = "USER_ID", unique = true, nullable = false)
    private String userId;

//getters and setters
}
</code>```

And i am designing a html page to get above input from user. As per the tutorial they are creating a DTO class with same variables which are in the DAO entity class and implementing JSR303 validation after that attaching that DTO to the form like below.

```<code><sf:form action="/addUser" commandName="userDTO"
                method="post">
//input text boxes

</sf:form>
</code>```

Its difficult to understand why we need to create a same DAO Entity class again without hibernate annotations and the same variables in the name of DTO. Please share some guidelines.

Is it a best practice or is it any performance / structural  reason that we need to create DTO class for html form.

What will happen if we directly attach DAO entity class with form.

Please give some ideas / guidelines.

答:
The simple answer to this question:

consider an example:

To get a summary of customer orders, That would have each row be taken from entities such as customers, addresses, products, orders etc. In such a case it is wasteful and slow to load all the entities to memory to render them in the flat search results screen.

Now, whenever the view changes it's not possible to change the entities(it will be time-consuming) but DTOs can be updated or deleted easily when as they are only used to fetch data and render them.

It is strongly recommended putting as much business logic into entities and try to have all the code which creates and connects entities default/package protected and as hidden as possible. When you do that you get the better OO design. An example would be the Order entity has a method getOrderItems to list the OrderItem entities but a protected setOrderItems method. The client would invoke a public method on the Order called addItem which took all the fields needed to construct the OrderItem entry internally using a protected constructor and add it into its list of order items. The Order becomes a "root/aggregate entity" which manages the relations and business logic of subordinate entities. This is a more naturally OO design than having "behaviourless" DTOs with the business logic entirely in service classes; or worse spread out across UI code. Have the service classes that query and load root entities then call method on the root entities that contain the business logic. That way different service class methods that work with the same root entities won't duplicate logic as the logic will be within the entities that are shared.

In simple words: If your entities are dumb with no logic then they are just DTOs.

Body:
I am learning hibernate with spring. While implementing i am creating entity class like below

@Entity
@Table(name = "USER_DETAILS", uniqueConstraints = @UniqueConstraint(columnNames = "USER_ID"))
public class UserInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "USER_KEY", unique = true, nullable = false)
    private Long userKey;

    @Column(name = "USER_ID", unique = true, nullable = false)
    private String userId;

//getters and setters
}

And i am designing a html page to get above input from user. As per the tutorial they are creating a DTO class with same variables which are in the DAO entity class and implementing JSR303 validation after that attaching that DTO to the form like below.

<sf:form action="/addUser" commandName="userDTO"
                method="post">
//input text boxes

</sf:form>

Its difficult to understand why we need to create a same DAO Entity class again without hibernate annotations and the same variables in the name of DTO. Please share some guidelines.

Is it a best practice or is it any performance / structural  reason that we need to create DTO class for html form.

What will happen if we directly attach DAO entity class with form.

Please give some ideas / guidelines.


问:
Set width of custom InfoWindow in Google Maps api v2
I created markers on the map. When I click on them, the custom info windows are always as wide as the screen.

I tried setting layout_width="200dp" but that didn't help. I also tried setting

```<code>view.setLayoutParams(new LayoutParams(GetDipsFromPixel(200), GetDipsFromPixel(300)));
</code>```

I can set the width of the textviews by setting snippetUi.setWidth(GetDipsFromPixel(200)); but the layout still remains screen wide.

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="#FFFFFF"
    android:layout_marginLeft="30dp"
    android:layout_marginRight="30dp"
    android:padding="10dp" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="#FFFFFF"
        android:gravity="center_vertical">

        <ImageView
            android:id="@+id/worldmap_infowindow_profileimg"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:src="@drawable/noimage" />

        <TextView
            android:id="@+id/worldmap_infowindow_username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="To do No.2."
            android:textColor="#000000"
            android:textSize="16sp"
            android:textStyle="bold"
            android:paddingLeft="5dp"/>
    </LinearLayout>

    <View android:id="@+id/separator"
         android:background="#ababab"
         android:layout_width = "fill_parent"
         android:layout_marginTop="3dp"
         android:layout_marginBottom="3dp"
         android:layout_height="1dp"/>

    <TextView
        android:id="@+id/worldmap_infowindow_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="See the Giza Pyramids"
        android:textColor="#000000"
        android:textSize="16sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/worldmap_infowindow_details"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="It was fascinating! It's a shame that it was raining, though."
        android:textColor="#000000"
        android:textSize="14sp"
        android:textStyle="normal" />

</LinearLayout>
</code>```

Class:

```<code> private class CustomInfoWindowAdapter implements InfoWindowAdapter {

       private View view;

       public CustomInfoWindowAdapter() {
            view = getLayoutInflater().inflate(R.layout.custom_infowindow, null);
       }

       @Override
       public View getInfoContents(Marker marker) {

           if (WorldMap.this.myMarker != null
                   && WorldMap.this.myMarker.isInfoWindowShown()) {
               WorldMap.this.myMarker.hideInfoWindow();
               WorldMap.this.myMarker.showInfoWindow();
           }
           return null;
       }

       @Override
       public View getInfoWindow(final Marker marker) {
           WorldMap.this.myMarker = marker;

           final String title = marker.getTitle();
           final TextView titleUi = ((TextView) view.findViewById(R.id.worldmap_infowindow_name));
           if (title != null) {
               titleUi.setText(title);
           } else {
               titleUi.setText("");
           }

           final String snippet = marker.getSnippet();
           final TextView snippetUi = ((TextView) view.findViewById(R.id.worldmap_infowindow_details));
           if (snippet != null) {
               snippetUi.setText(snippet);
           } else {
               snippetUi.setText("");
           }

           return view;
       }
   }
</code>```

答:
Just create the parent layout with "wrap_content" and a child layout with the desired size:</p>

```<code><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:orientation="vertical">

    <!-- This layout defines the desired size -->
    <LinearLayout
        android:layout_width="240dp"
        android:layout_height="320dp"
        android:orientation="vertical">

        <!-- Your views here -->

    </LinearLayout>

</LinearLayout>
</code>```

Body:
I created markers on the map. When I click on them, the custom info windows are always as wide as the screen.

I tried setting layout_width="200dp" but that didn't help. I also tried setting

view.setLayoutParams(new LayoutParams(GetDipsFromPixel(200), GetDipsFromPixel(300)));

I can set the width of the textviews by setting snippetUi.setWidth(GetDipsFromPixel(200)); but the layout still remains screen wide.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="#FFFFFF"
    android:layout_marginLeft="30dp"
    android:layout_marginRight="30dp"
    android:padding="10dp" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="#FFFFFF"
        android:gravity="center_vertical">

        <ImageView
            android:id="@+id/worldmap_infowindow_profileimg"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:src="@drawable/noimage" />

        <TextView
            android:id="@+id/worldmap_infowindow_username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="To do No.2."
            android:textColor="#000000"
            android:textSize="16sp"
            android:textStyle="bold"
            android:paddingLeft="5dp"/>
    </LinearLayout>

    <View android:id="@+id/separator"
         android:background="#ababab"
         android:layout_width = "fill_parent"
         android:layout_marginTop="3dp"
         android:layout_marginBottom="3dp"
         android:layout_height="1dp"/>

    <TextView
        android:id="@+id/worldmap_infowindow_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="See the Giza Pyramids"
        android:textColor="#000000"
        android:textSize="16sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/worldmap_infowindow_details"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="It was fascinating! It's a shame that it was raining, though."
        android:textColor="#000000"
        android:textSize="14sp"
        android:textStyle="normal" />

</LinearLayout>

Class:

 private class CustomInfoWindowAdapter implements InfoWindowAdapter {

       private View view;

       public CustomInfoWindowAdapter() {
            view = getLayoutInflater().inflate(R.layout.custom_infowindow, null);
       }

       @Override
       public View getInfoContents(Marker marker) {

           if (WorldMap.this.myMarker != null
                   && WorldMap.this.myMarker.isInfoWindowShown()) {
               WorldMap.this.myMarker.hideInfoWindow();
               WorldMap.this.myMarker.showInfoWindow();
           }
           return null;
       }

       @Override
       public View getInfoWindow(final Marker marker) {
           WorldMap.this.myMarker = marker;

           final String title = marker.getTitle();
           final TextView titleUi = ((TextView) view.findViewById(R.id.worldmap_infowindow_name));
           if (title != null) {
               titleUi.setText(title);
           } else {
               titleUi.setText("");
           }

           final String snippet = marker.getSnippet();
           final TextView snippetUi = ((TextView) view.findViewById(R.id.worldmap_infowindow_details));
           if (snippet != null) {
               snippetUi.setText(snippet);
           } else {
               snippetUi.setText("");
           }

           return view;
       }
   }

Body:
Just create the parent layout with "wrap_content" and a child layout with the desired size:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:orientation="vertical">

    <!-- This layout defines the desired size -->
    <LinearLayout
        android:layout_width="240dp"
        android:layout_height="320dp"
        android:orientation="vertical">

        <!-- Your views here -->

    </LinearLayout>

</LinearLayout>


问:
How routing to home can be done in React
I am new to React.I am trying to change the route inside a function.I am used react-router-dom for routing.I used "react-router-dom": "^4.1.1".The function is,

```<code> LogIn(email, password){

            this.props.LogInAction(email, password);
            if(this.props.loginstatus == true){

                    /* Here I need to go to '/home' */

            }
</code>```

答:
If you use react-router, inside you class </p>

```<code>pushHistory() {
        this.props.history.push("/");
    }

LogIn(email, password){

            this.props.LogInAction(email, password);
            if(this.props.loginstatus == true){

                   this.props.history.push("/");

            }
</code>```

<p>and your routes wrapped like this: </p>

```<code>import {BrowserRouter, Route, Switch} from "react-router-dom";

    <BrowserRouter>
                <div>
                    <Switch>
                    <Route exact={true} path="/" component={ App }/>
                    <Route exact path="/users" component={ UserList }/>
                    <Route exact path="/user/new" component={ UserCreate }/>
                    <Route path="/users/:id" component={ UserDetail }/>
                    </Switch>
                </div>
            </BrowserRouter>
</code>```

Body:
I am new to React.I am trying to change the route inside a function.I am used react-router-dom for routing.I used "react-router-dom": "^4.1.1".The function is,

 LogIn(email, password){

            this.props.LogInAction(email, password);
            if(this.props.loginstatus == true){

                    /* Here I need to go to '/home' */

            }

Body:
If you use react-router, inside you class

pushHistory() {
        this.props.history.push("/");
    }

LogIn(email, password){

            this.props.LogInAction(email, password);
            if(this.props.loginstatus == true){

                   this.props.history.push("/");

            }

and your routes wrapped like this:

import {BrowserRouter, Route, Switch} from "react-router-dom";

    <BrowserRouter>
                <div>
                    <Switch>
                    <Route exact={true} path="/" component={ App }/>
                    <Route exact path="/users" component={ UserList }/>
                    <Route exact path="/user/new" component={ UserCreate }/>
                    <Route path="/users/:id" component={ UserDetail }/>
                    </Switch>
                </div>
            </BrowserRouter>


问:
Unable to view value in textbox after binding in angularjs
Hi I am developing Angularjs application. I am trying to bind value to textbox as below.

```<code><ul>
    <li ng-repeat="screen in screenMap">
        <input type="text" ng-model="screenname" value="{{screen.scrn_name}}" />
    </li>
</ul>
</code>```

After binding value to textbox, Textbox does not show any value. But when i see in browser i can see below value is binded

```<code> <input type="text" ng-model="screenname" value="USerProfile" class="ng-pristine ng-untouched ng-valid">
</code>```

May i know why i am not able to see value in textbox? Any help would be appreciated. Thank you.

答: ng-model="your_value" I think it will work.</p>

Body:
Hi I am developing Angularjs application. I am trying to bind value to textbox as below.

        <input type="text" ng-model="screenname" value="{{screen.scrn_name}}" />

After binding value to textbox, Textbox does not show any value. But when i see in browser i can see below value is binded

 <input type="text" ng-model="screenname" value="USerProfile" class="ng-pristine ng-untouched ng-valid">

May i know why i am not able to see value in textbox? Any help would be appreciated. Thank you.


问:
Convert simple array into two-dimensional array (matrix)
Imagine I have an array:

```<code>A = Array(1, 2, 3, 4, 5, 6, 7, 8, 9);
</code>```

And I want it to convert into 2-dimensional array (matrix of N x M), for instance like this:

```<code>A = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9));
</code>```

Note, that rows and columns of the matrix is changeable.

答:
How about something like:

```<code>var matrixify = function(arr, rows, cols) {
    var matrix = [];
    if (rows * cols === arr.length) {
        for(var i = 0; i < arr.length; i+= cols) {
            matrix.push(arr.slice(i, cols + i));
        }
    }

    return matrix;
};

var a = [0, 1, 2, 3, 4, 5, 6, 7];
matrixify(a, 2, 4);
</code>```

http://jsfiddle.net/andrewwhitaker/ERAUs/

ContentLicense: CC BY-SA 4.0

Body:
Imagine I have an array:

A = Array(1, 2, 3, 4, 5, 6, 7, 8, 9);

And I want it to convert into 2-dimensional array (matrix of N x M), for instance like this:

A = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9));

Note, that rows and columns of the matrix is changeable.

Body:
How about something like:

var matrixify = function(arr, rows, cols) {
    var matrix = [];
    if (rows * cols === arr.length) {
        for(var i = 0; i < arr.length; i+= cols) {
            matrix.push(arr.slice(i, cols + i));
        }
    }

    return matrix;
};

var a = [0, 1, 2, 3, 4, 5, 6, 7];
matrixify(a, 2, 4);

http://jsfiddle.net/andrewwhitaker/ERAUs/


问:
openstack identity api get response error code
im intern student. I have a question .

Im working to bug/fix on an Openstack cloud , Javascript and nodejs web app. Now im fixing toastr.error messages and then translate message's language.

How can i get openstack-identity-api response error code ? I have some documents about error code's reason like this.

Code  Reason

204 - No Content  The server has fulfilled the request.

Error¶

Code  Reason 400 - Bad Request    Some content in the request was invalid

401 - Unauthorized    User must authenticate before making a request.

403 - Forbidden   Policy does not allow current user to do this
  operation.

404 - Not Found   The requested resource could not be found.

409 - Conflict    This operation conflicted with another operation on
  this resource.

https://developer.openstack.org/api-ref/identity/v3/?expanded=change-password-for-user-detail

Example :

```<code>if(resp.error === 401){
     toastr.error("Authentication failure. Please contact the system administrator.");}
</code>```

答: Could you please explain your ask here? The Openstack API document you have referred clearly shows the response codes and what might be the cause for each error code. What additional info you would require? </p>

Body:
im intern student. I have a question .

Im working to bug/fix on an Openstack cloud , Javascript and nodejs web app. Now im fixing toastr.error messages and then translate message's language.

How can i get openstack-identity-api response error code ? I have some documents about error code's reason like this.

Code  Reason

204 - No Content  The server has fulfilled the request.

Error¶

Code  Reason 400 - Bad Request    Some content in the request was invalid

401 - Unauthorized    User must authenticate before making a request.

403 - Forbidden   Policy does not allow current user to do this
  operation.

404 - Not Found   The requested resource could not be found.

409 - Conflict    This operation conflicted with another operation on
  this resource.

https://developer.openstack.org/api-ref/identity/v3/?expanded=change-password-for-user-detail

Example :

if(resp.error === 401){
     toastr.error("Authentication failure. Please contact the system administrator.");}


问:
How to Formatting XML data using C#, JQuery or HTML
How i can get following XML data to easy understand format.

Input XML Data

```<code><?xml version="1.0"?>
<user>
<details><name>xyz</name><class>mno</class><city>pqr</city></details>
<info><id>321</id><code>654</code></info>
</user>
</code>```

Expected Output

```<code><?xml version="1.0"?>
<user>
    <details>
        <name>xyz</name>
        <class>mno</class>
        <city>pqr</city>
    </details>
    <info>
        <id>321</id>
        <code>654</code>
    </info>
</user>
</code>```

Anyone idea how to do this using HTML,JQuery and C#.

Thank you

答:
Try with the below one(With C#).

```<code>using System;
using System.IO;
using System.Xml;

namespace FormatXMLStringConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string rawStringXML = "<?xml version='1.0'?><user><details><name>xyz</name><class>mno</class><city>pqr</city></details><info><id>321</id><code>654</code></info></user>";
            XmlDocument xmlDoc = new XmlDocument();
            StringWriter sw = new StringWriter();
            xmlDoc.LoadXml(rawStringXML);
            xmlDoc.Save(sw);
            string formattedXml = sw.ToString();
            Console.WriteLine(formattedXml);
            Console.Read();
        }
    }
}
</code>```

OUTPUT

Check and let me know if it solves your problem.

Body:
How i can get following XML data to easy understand format.

Input XML Data

<?xml version="1.0"?>
<user>
<name>xyz</name><class>mno</class><city>pqr</city>
<info><id>321</id>654</info>
</user>

Expected Output

<?xml version="1.0"?>
<user>

        <name>xyz</name>
        <class>mno</class>
        <city>pqr</city>

    <info>
        <id>321</id>
        654
    </info>
</user>

Anyone idea how to do this using HTML,JQuery and C#.

Thank you

Body:
Try with the below one(With C#).

using System;
using System.IO;
using System.Xml;

namespace FormatXMLStringConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string rawStringXML = "<?xml version='1.0'?><user><details><name>xyz</name><class>mno</class><city>pqr</city></details><info><id>321</id><code>654</code></info></user>";
            XmlDocument xmlDoc = new XmlDocument();
            StringWriter sw = new StringWriter();
            xmlDoc.LoadXml(rawStringXML);
            xmlDoc.Save(sw);
            string formattedXml = sw.ToString();
            Console.WriteLine(formattedXml);
            Console.Read();
        }
    }
}

OUTPUT

Check and let me know if it solves your problem.


问:
To create an array that contains each digit as separate element from integer in JavaScript
My understanding is that bellow code will create an array name digits which contains all digits from n, I'm I right?

var n =  123456789;
var digits = (""+n).split("");

But I did'n understood (""+n) ?
Can anyone help me?
Thanks in advance.

答:
When concat a number with string, js cast it to string. In your code, n is number, but when concat with a empty string(""), casting to string. In other way you can call toString() function. You can run follow snippet to try it

var n = 123456789;

console.log(typeof n); //number
console.log(typeof (""+n)); //string
console.log((""+n).split(""));
console.log(n.toString().split(""));```


答:
Let's say you want to update a row on a single condition (e.g. change = 1 when percent < 0.11 and 0 otherwise). You would do something like this:

```<code>val newDF = df.withColumn("change", when($"percent" < 0.11, lit(1)).otherwise(lit(0))
</code>```

When you are doing addition changes just chain them:

```<code>val newDFCombined = newDF.withColumn("ecpc", when($"percent" < 0.11, myFunc1($"values").otherwise(myFunc2($"values"))))
</code>```

where myFunc1 and MyFunc2 are the functions to calculate the value you want.

Title: How to update row based on multiple condition

Body:
I have a df

+------+-------+-----+
|values|percent|ecpc |
+------+-------+-----+
|  010 |  0.11 |    5|
|  100 |  0.22 |    4|
|  001 |  0.33 |    3|
|  011 |  0.01 |    5|
|  101 |  0.005|    4|
|  110 |  0.11 |    3|
|  000 |  0.21 |    5|
|  111 |0.0001 |    4|
+------+-------+-----+

If percent < 0.01 ,I wanna change values one of 1 to 0.
AND Changed percent > 0.01, change ecpc to new ecpc.

EX: for values 111, percent<0.01, change one of 1 to 0, like 101,
still percent< 0.01, change other 1, like 110, percent>0.01  is 0.11,
change another 1, like 011, percent>0.01 is 0.01. 0.01 <0.11 .
Update ecpc to 5 when values = 111.

Final DF like :

+------+-------+-----+------+
|values|percent|ecpc |change|
+------+-------+-----+------+
|  010 |  0.11 |    5|     0|
|  100 |  0.22 |    4|     0|
|  001 |  0.33 |    3|     0|
|  011 |  0.01 |    5|     0|
|  101 |  0.005|    5|     1|
|  110 |  0.11 |    3|     0|
|  000 |  0.21 |    5|     0|
|  111 |0.0001 |    3|     1|
+------+-------+-----+------+

Body:
Let's say you want to update a row on a single condition (e.g. change = 1 when percent < 0.11 and 0 otherwise). You would do something like this:

val newDF = df.withColumn("change", when($"percent" < 0.11, lit(1)).otherwise(lit(0))

When you are doing addition changes just chain them:

val newDFCombined = newDF.withColumn("ecpc", when($"percent" < 0.11, myFunc1($"values").otherwise(myFunc2($"values"))))

where myFunc1 and MyFunc2 are the functions to calculate the value you want.


问:
Update...Set...From...Where query is affecting all rows and not specific ones
The below query should only affect the row titled 'F0085'. However, it has affected all the rows. Setting the address to 'test' on every Job_No.

```<code>UPDATE TBTest.dbo.Site
SET Address ='FDAN'
FROM Jobs
WHERE Job_No = 'F0085'
</code>```

This is the first table:

答:
```<code>UPDATE TBTest.dbo.Site  ST
INNER JOIN Jobs JB ON JB.Job_No=ST.JOB_NO
SET ST.Address =JB.Address
</code>```

Try above query.

Body:
The below query should only affect the row titled 'F0085'. However, it has affected all the rows. Setting the address to 'test' on every Job_No.

UPDATE TBTest.dbo.Site
SET Address ='FDAN'
FROM Jobs
WHERE Job_No = 'F0085'

This is the first table:

Body:
UPDATE TBTest.dbo.Site  ST
INNER JOIN Jobs JB ON JB.Job_No=ST.JOB_NO
SET ST.Address =JB.Address

Try above query.


问:
iPhone Icons retina/normal with Ending: @2x.png
My question is about TabBar-Icons:
I define standartsized TabBarIcons (20x20) and for retina resolution I'll just add the same image in big (40x40) and name it xxx@2.png.

Thats it, Am I right ?

cheers Simon

答: I believe Apple recommends that tabbar icons be 30x30 (xxx.png) and 60x60 (xxx@2x.png). The names are correct.</p>


问:
How to count total number of table rows from ajax response? How to create search field for that table?
I am getting table data from ajax response like this :

```<code>function fetch_data(){
  $.ajax({
    url: "menu_table.php",
    method: "POST",
    success: function(data) {
      $('#menu_table_data').html(data);
    }
  });
}

fetch_data();
</code>```

Table:

```<code><table id="menu_table">
  <thead>
    <tr>
      <th class="centerText" data-field="item_id">ID</th>
      <th class="centerText" data-field="name">Name</th>
      <th class="centerText" data-field="price">Price</th>
      <th class="centerText" data-field="type">Type</th>
      <th class="centerText" data-field="image">Image</th>
      <th class="centerText" data-field="description">Description</th>
      <th class="centerText" data-field="cooking">Instructions</th>
      <th class="centerText" data-field="ingredients">Ingredients</th>
      <th class="centerText" data-field="warnings">Warnings</th>
      <th class="centerText" data-field="Storage">Storage</th>
      <th class="centerText" data-field="Size">Size</th>
      <th class="centerText" data-field="edit">Edit</th>
      <th class="centerText" data-field="delete">Delete</th>
    </tr>
  </thead>
  <tbody style="text-align:center;" id="menu_table_data"></tbody>
</table>
</code>```

How do I count total number of rows from ajax response?

How can I create a search field to search from this table?

menu_table.php:

```<code>while($data = mysqli_fetch_array($search))
{
$output .= '<tr><td>'.$data['id'].'</td>
            <td><div class="text_area">'.$data['name'].'</div></td>
            <td>'.$data['price'].'</td>
            <td>'.$data['type'].'</td>
            <td><div id="div_image">
            <img src="uploaded_images/'.$data['image'].'" class="thumbnail" height="100" width="80" /></div></td>
            <td><div class="text_area">'.$data['description'].'</div></td>
            <td><div class="text_area">'.$data['cooking_instructions'].'<div></td>
            <td><div class="text_area">'.$data['ingredients'].'</div></td>
            <td><div class="text_area">'.$data['allergen_warnings'].'</div></td>
            <td>'.$data['storage_instructions'].'</td>
            <td>'.$data['case_size'].'</td>   <td><a class="btn btn-primary glyphicon glyphicon-edit" role="button" onclick="EditModal(`'.$data['id'].'`,`'.$data['name'].'`,`'.$data['price'].'`,`'.$data['description'].'`,`'.$data['type'].'`,`'.$data['cooking_instructions'].'`,`'.$data['ingredients'].'`,`'.$data['allergen_warnings'].'`,`'.$data['storage_instructions'].'`,`'.$data['case_size'].'`,`'."uploaded_images/".$data['image'].'`)"></a></td>   <td><a class="btn btn-danger glyphicon glyphicon-remove" role="button" onclick="DeleteModal('.$data['id'].')"></a></td><tr>';}
</code>```

答:
If you wanna search only on page you can use that :

```<code>$.extend($.expr[":"], {
        "containsIN": function(elem, i, match, array) {
            return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
        }
    });
</code>```

you can use that html onKeyUp:

```<code>function searchOnKeyUp(input,selector){
        $(selector).each(function(){ $(this).hide(); })
        $(selector + ':containsIN('+input.value+')').show();
    }
</code>```

And for other question I can say that I think you can use like that:

```<code>$('#menu_table_data').children('tr').length;
</code>```

Body:
I am getting table data from ajax response like this :

function fetch_data(){
  $.ajax({
    url: "menu_table.php",
    method: "POST",
    success: function(data) {
      $('#menu_table_data').html(data);
    }
  });
}

fetch_data();

Table:

      ID
      Name
      Price
      Type
      Image
      Description
      Instructions
      Ingredients
      Warnings
      Storage
      Size
      Edit
      Delete

How do I count total number of rows from ajax response?

How can I create a search field to search from this table?

menu_table.php:

while($data = mysqli_fetch_array($search))
{
$output .= '
'.$data['id'].'

'.$data['name'].'

            '.$data['price'].'
            '.$data['type'].'

'.$data['description'].'

'.$data['cooking_instructions'].'

'.$data['ingredients'].'

'.$data['allergen_warnings'].'

            '.$data['storage_instructions'].'
            '.$data['case_size'].'	   <a class="btn btn-primary glyphicon glyphicon-edit" role="button" onclick="EditModal(`'.$data['id'].'`,`'.$data['name'].'`,`'.$data['price'].'`,`'.$data['description'].'`,`'.$data['type'].'`,`'.$data['cooking_instructions'].'`,`'.$data['ingredients'].'`,`'.$data['allergen_warnings'].'`,`'.$data['storage_instructions'].'`,`'.$data['case_size'].'`,`'."uploaded_images/".$data['image'].'`)">
';}

Body:
If you wanna search only on page you can use that :

$.extend($.expr[":"], {
        "containsIN": function(elem, i, match, array) {
            return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
        }
    });

you can use that html onKeyUp:

function searchOnKeyUp(input,selector){
        $(selector).each(function(){ $(this).hide(); })
        $(selector + ':containsIN('+input.value+')').show();
    }

And for other question I can say that I think you can use like that:

$('#menu_table_data').children('tr').length;


问:
Can jBPM Executor be used as a scheduler for Business Processes?

Can jBPM executor be used to schedule WHOLE business processes (or would such approach be a misuse)?

Short explanation of logic behind that question: almost all the examples I have found so far present jBPM executor as a way to: asynchronously invoke PARTS of business processes (work item handlers) or simple classes which contain some business logic.

Moreover this is an extract from jBPM Command interface javadoc (executor operates on Commands):

```<code>/**
 * Executor's Command are dedicated to contain purely business logic that should be executed.
 * It should not have any reference to underlying process engine and should not be concerned
 * with any process runtime related logic such us completing work item, sending signals, etc.
 * ...
 */
</code>```

On the other hand I have found an entry on Maciej Swiderski's blog in which it is written that executor supports: 'async start process instance'.

In case WHOLE business processes can be started via jBPM executor, do you have any experience in extending executor functionalities?
What I mean is adding more Quartz-like features e.g. support for business calendars, job chaining, job grouping.

Thanks in advance for all the answers.

答:
I've talked with Maciej Swiderski (core developer of jBPM) on jBPM IRC Channel and the answers are:

ad 1. Yes, you could do it with this command: https://github.com/kiegroup/jbpm/blob/master/jbpm-flow/src/main/java/org/jbpm/process/core/async/AsyncStartProcessCommand.java

ad 2. Job Executor can not easily be extended to provide Quartz-like features. It serves different purpose. One should use e.g. Quartz when such advanced options are needed.

Body:
Can jBPM executor be used to schedule WHOLE business processes (or would such approach be a misuse)?

Short explanation of logic behind that question: almost all the examples I have found so far present jBPM executor as a way to: asynchronously invoke PARTS of business processes (work item handlers) or simple classes which contain some business logic.

Moreover this is an extract from jBPM Command interface javadoc (executor operates on Commands):

/**
 * Executor's Command are dedicated to contain purely business logic that should be executed.
 * It should not have any reference to underlying process engine and should not be concerned
 * with any process runtime related logic such us completing work item, sending signals, etc.
 * ...
 */

On the other hand I have found an entry on Maciej Swiderski's blog in which it is written that executor supports: 'async start process instance'.

In case WHOLE business processes can be started via jBPM executor, do you have any experience in extending executor functionalities?
What I mean is adding more Quartz-like features e.g. support for business calendars, job chaining, job grouping.

Thanks in advance for all the answers.


问:
How to refresh Android listview evry 10 seconds
Im very new on Android. im making this teturial but i have a problem on refresh and can't understand how to refresh my listview </p>

```<code>        // Creating volley request obj
    JsonArrayRequest movieReq = new JsonArrayRequest(url,
            new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    Log.d(TAG, response.toString());
                    hidePDialog();

                    // Parsing json
                    for (int i = 0; i < response.length(); i++) {
                        try {

                            JSONObject obj = response.getJSONObject(i);
                            Movie movie = new Movie();
                            movie.setTitle(obj.getString("title"));
                            movie.setThumbnailUrl(obj.getString("image"));
                            movie.setRating(((Number) obj.get("rating"))
                                    .doubleValue());
                            movie.setYear(obj.getInt("releaseYear"));

                            // Genre is json array
                            JSONArray genreArry = obj.getJSONArray("genre");
                            ArrayList<String> genre = new ArrayList<String>();
                            for (int j = 0; j < genreArry.length(); j++) {
                                genre.add((String) genreArry.get(j));
                            }
                            movie.setGenre(genre);

                            // adding movie to movies array
                            movieList.add(movie);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }

                    // notifying list adapter about data changes
                    // so that it renders the list view with updated data
                    adapter.notifyDataSetChanged();
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    VolleyLog.d(TAG, "Error: " + error.getMessage());
                    hidePDialog();

                }
            });

/** REFRESH HERE /**

 Thread t = new Thread() {

        @Override
        public void run() {
            try {
                while (!isInterrupted()) {
                    Thread.sleep(10000);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.e(TAG, "EVRY 10 SECOND START NOW ");

                            listView.invalidateViews();
                            listView.refreshDrawableState();
                            adapter.notifyDataSetChanged();

//                                Log.e(TAG, String.valueOf(movieList));

                            // fire the event

                        }
                    });
                }
            } catch (InterruptedException e) {
            }
        }
    };

    t.start();
    // Adding request to request queue
    AppController.getInstance().addToRequestQueue(movieReq);
</code>```

<p>i try all methods google... but no luck this notifyDataSetChanged() not working ... </p>

```<code> listView.invalidateViews();
listView.refreshDrawableState();
adapter.notifyDataSetChanged();
</code>```

答:
Use a Handler and its postDelayed method to invalidate the list's adapter as follows:

```<code>    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            adapter.notifyDataSetChanged();
            handler.postDelayed(this, 10 * 1000);
        }
    }, 10 * 1000);
</code>```

You must only update UI in the main (UI) thread.

By creating the handler in the main thread, you ensure that everything you post to the handler is run in the main thread also.

Body:
Im very new on Android. im making this teturial but i have a problem on refresh and can't understand how to refresh my listview

        // Creating volley request obj
    JsonArrayRequest movieReq = new JsonArrayRequest(url,
            new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    Log.d(TAG, response.toString());
                    hidePDialog();

                    // Parsing json
                    for (int i = 0; i < response.length(); i++) {
                        try {

                            JSONObject obj = response.getJSONObject(i);
                            Movie movie = new Movie();
                            movie.setTitle(obj.getString("title"));
                            movie.setThumbnailUrl(obj.getString("image"));
                            movie.setRating(((Number) obj.get("rating"))
                                    .doubleValue());
                            movie.setYear(obj.getInt("releaseYear"));

                            // Genre is json array
                            JSONArray genreArry = obj.getJSONArray("genre");
                            ArrayList<String> genre = new ArrayList<String>();
                            for (int j = 0; j < genreArry.length(); j++) {
                                genre.add((String) genreArry.get(j));
                            }
                            movie.setGenre(genre);

                            // adding movie to movies array
                            movieList.add(movie);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }

                    // notifying list adapter about data changes
                    // so that it renders the list view with updated data
                    adapter.notifyDataSetChanged();
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    VolleyLog.d(TAG, "Error: " + error.getMessage());
                    hidePDialog();

                }
            });

/** REFRESH HERE /**

 Thread t = new Thread() {

        @Override
        public void run() {
            try {
                while (!isInterrupted()) {
                    Thread.sleep(10000);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.e(TAG, "EVRY 10 SECOND START NOW ");

                            listView.invalidateViews();
                            listView.refreshDrawableState();
                            adapter.notifyDataSetChanged();

//                                Log.e(TAG, String.valueOf(movieList));

                            // fire the event

                        }
                    });
                }
            } catch (InterruptedException e) {
            }
        }
    };

    t.start();
    // Adding request to request queue
    AppController.getInstance().addToRequestQueue(movieReq);

i try all methods google... but no luck this notifyDataSetChanged() not working ...

 listView.invalidateViews();
listView.refreshDrawableState();
adapter.notifyDataSetChanged();

Body:
Use a Handler and its postDelayed method to invalidate the list's adapter as follows:

    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            adapter.notifyDataSetChanged();
            handler.postDelayed(this, 10 * 1000);
        }
    }, 10 * 1000);

You must only update UI in the main (UI) thread.

By creating the handler in the main thread, you ensure that everything you post to the handler is run in the main thread also.


问:
Moving from Gulp to the Bundler and Minifier Extension
we're attempting to move away from Gulp and instead using the integrated VS bundler and compiler extension.  It generates the output files of site.js and vendor.js fine, but when you reload the page, we get a uncaught error in the vendor.js file, which is odd, as the gulp version (which doesn't give us the error) of vendor.js is identical.  I then thought this may be something to do with sizzlejs (included in the jquery version (1.11.3) we're using, but I couldn't debug it or know where to start and then I removed (from the gulpbuild) the uglify-js package and I now get the same error on gulp as I do with the new non-gulp build, so do I assume it's something to do with uglify? ...

Any help or thoughts really appreciated.

答:
I've worked it out, but I'll add to here for anyone else that may have the problem.

Quite simply really, one of the bundled folders had 2 vendor js files exactly the same for some very odd reason. :-)


问:
Does every table need a primary key?
Take the Loan table below as an example. Does it require any primary key?

Loan Table

答:
Does every table NEED a primary key: No.

SHOULD every table have a primary key: Yes. There may be situations where a table doesn't need a primary key, but those are rare and in general every table should have one. This is because you will want to uniquely identify a record and it becomes difficult to work with records that don't have primary keys.

In your case, YES your loan table should have a primary key. As Andre has already said in his answer it should be a combination of the DocumentID and the EmployeeID.

At the risk of introducing some confusion: Use either DocumentID + EmployeeID or EmployeeID + DocumentID. The order can make a difference. If you go for say DocumentID + EmployeeID (in that order) then the database will use the primary key when searching on DocumentID plus EmployeeID (any order in your query), and for searches on just the DocumentID but won't use it when searching on just EmployeeID.

Title: Does every table need a primary key?


问:
How to get and update last string after some character like '\ ' in python dataframe
How to split df['FullString'] and get the last phrase after '\' then update to df['Splitted']?

df:

```<code>FullString                          Splitted
2\0\2\0\R\A\T\I\O\0\0\0123456789    0123456789
2\0\2\0\R\A\T\I\O\0\0\25632589      25632589
</code>```

答:
that can be done easily like this:

```<code>df['Splitted'] = [s.split('\\')[-1] for s in df['FullString']]
print(df)
</code>```

output:

```<code>                         FullString    Splitted
0  2\0\2\0\R\A\T\I\O\0\0\0123456789  0123456789
1    2\0\2\0\R\A\T\I\O\0\0\25632589    25632589
</code>```

PS:

you can start with only FullString column like this one:

```<code>                         FullString
0  2\0\2\0\R\A\T\I\O\0\0\0123456789
1    2\0\2\0\R\A\T\I\O\0\0\25632589
</code>```

Body:
How to split df['FullString'] and get the last phrase after '\' then update to df['Splitted']?

df:

FullString                          Splitted
2\0\2\0\R\A\T\I\O\0\0\0123456789    0123456789
2\0\2\0\R\A\T\I\O\0\0\25632589      25632589

Body:
that can be done easily like this:

df['Splitted'] = [s.split('\\')[-1] for s in df['FullString']]
print(df)

output:

                         FullString    Splitted
0  2\0\2\0\R\A\T\I\O\0\0\0123456789  0123456789
1    2\0\2\0\R\A\T\I\O\0\0\25632589    25632589

PS:

you can start with only FullString column like this one:

                         FullString
0  2\0\2\0\R\A\T\I\O\0\0\0123456789
1    2\0\2\0\R\A\T\I\O\0\0\25632589


答:
Put your Volley request code inside a method, let's name id fetchData();

Then you can call your service again after 10 seconds by the below code:

```<code>final Handler mHandler = new Handler();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10000);
                        mHandler.post(new Runnable() {

                            @Override
                            public void run() {
                                // Write your code here to call the method.
                              fetchData();
                            }
                        });
                    } catch (Exception e) {
                        // TODO: handle exception here
                        e.printStackTrace();
                    }
                }
            }
        }).start();
</code>```

Try this and lo let me know if any problem.

Title: How to refresh Android listview evry 10 seconds

Body:
Put your Volley request code inside a method, let's name id fetchData();

Then you can call your service again after 10 seconds by the below code:

final Handler mHandler = new Handler();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10000);
                        mHandler.post(new Runnable() {

                            @Override
                            public void run() {
                                // Write your code here to call the method.
                              fetchData();
                            }
                        });
                    } catch (Exception e) {
                        // TODO: handle exception here
                        e.printStackTrace();
                    }
                }
            }
        }).start();

Try this and lo let me know if any problem.


问:
How to pass ERROR: more than one row returned by a subquery used as an expression
The thing is, that I need to return the books and their COUNT, which were in a possession of a reader less times than the AVG of all books being taken by readers. I have prepared this code:

```<code>SELECT book.name, book.publisher, COUNT(specimen.taken) FROM book
LEFT JOIN specimen ON book.isbn = specimen.isbn
WHERE (SELECT COUNT(specimen.taken) FROM specimen
GROUP BY specimen.isbn)  <
(SELECT CAST(COUNT(specimen.nr) / COUNT(specimen.taken) AS
DECIMAL(10,2))
FROM specimen)
GROUP BY book.name, book.publisher;
</code>```

but since the result of the first SELECT in the WHERE clause returns the numbers of the times each book was taken, I cannot compare them with the overall average concluded by the second SELECT. Thus I get

ERROR: more than one row returned by a subquery used as an expression.

Is this the part where I should be using select within selects select or something? All help is appreciated!

答:
The main issue with your query is that you want a HAVING clause, not a WHERE clause:

```<code>SELECT b.name, b.publisher, COUNT(*)
FROM book b LEFT JOIN
     specimen s
     ON b.isbn = s.isbn
GROUP BY b.name, b.publisher
HAVING COUNT(*) < (SELECT COUNT(*) * 1.0 / COUNT(DISTINCT s2.isbn)
                   FROM specimen s2
                  );
</code>```

You are not calculating the average correctly either.  The above is my best guess.

Note:  The "right" way to write the query uses window functions, but I'm guessing you have not learned that yet.

Body:
The thing is, that I need to return the books and their COUNT, which were in a possession of a reader less times than the AVG of all books being taken by readers. I have prepared this code:

SELECT book.name, book.publisher, COUNT(specimen.taken) FROM book
LEFT JOIN specimen ON book.isbn = specimen.isbn
WHERE (SELECT COUNT(specimen.taken) FROM specimen
GROUP BY specimen.isbn)  <
(SELECT CAST(COUNT(specimen.nr) / COUNT(specimen.taken) AS
DECIMAL(10,2))
FROM specimen)
GROUP BY book.name, book.publisher;

but since the result of the first SELECT in the WHERE clause returns the numbers of the times each book was taken, I cannot compare them with the overall average concluded by the second SELECT. Thus I get

ERROR: more than one row returned by a subquery used as an expression.

Is this the part where I should be using select within selects select or something? All help is appreciated!

Body:
The main issue with your query is that you want a HAVING clause, not a WHERE clause:

SELECT b.name, b.publisher, COUNT(*)
FROM book b LEFT JOIN
     specimen s
     ON b.isbn = s.isbn
GROUP BY b.name, b.publisher
HAVING COUNT(*) < (SELECT COUNT(*) * 1.0 / COUNT(DISTINCT s2.isbn)
                   FROM specimen s2
                  );

You are not calculating the average correctly either.  The above is my best guess.

Note:  The "right" way to write the query uses window functions, but I'm guessing you have not learned that yet.


问:
How to solve Instant Run on Android Studio Canary 5, 6 and 7
Since I upgraded to Android Studio Canary 5 I have had issues with Instant Run, it gives me the following error when Instant Run is Enable:

```<code>Information:Gradle tasks [:app:assembleDebug]
Error:C:\..etc.\app\build\intermediates\instant-run-support\debug\dependencies\AndroidManifest.xml:2 resource string/app_build_version_name (aka com.itbackyard.iels.client:string/app_build_version_name) not found
Error:java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.AaptException: AAPT2 link failed:
Error:com.android.builder.internal.aapt.AaptException: AAPT2 link failed:
Error:java.lang.RuntimeException: com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: Failed to execute aapt
Error:com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: Failed to execute aapt
Error:com.android.ide.common.process.ProcessException: Failed to execute aapt
Error:java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.AaptException: AAPT2 link failed:
Error:com.android.builder.internal.aapt.AaptException: AAPT2 link failed:
Information:BUILD FAILED in 1m 29s
Information:8 errors
Information:0 warnings
Information:See complete output in console
</code>```

My only solution was to disable Instant Run from settings. What I was able to find is this topic with out solution so far.

Any idea if this is still a bug or is there any work around till it gets fixed?

Here is my version information:

```<code>Android Studio 3.0 Canary 5
Build #AI-171.4141229, built on June 28, 2017
JRE: 1.8.0_152-release-884-b01 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
</code>```

Edit
I have now updated to

```<code>Android Studio 3.0 Canary 6
Build #AI-171.4163606, built on July 7, 2017
JRE: 1.8.0_152-release-884-b01 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
</code>```

And updated to Canary 7

```<code>Android Studio 3.0 Canary 7
Build #AI-171.4182969, built on July 14, 2017
JRE: 1.8.0_152-release-884-b01 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
</code>```

Still the same problem.

答:
Add this line gradle.properties file. it work for me

```<code>android.enableAapt2=false
</code>```

Android Studio 3.0 Canary 5

If your build fails due to resource processing issue. To temporarily disable AAPT, set android.enableAapt2=false in your gradle.properties file.

Body:
Since I upgraded to Android Studio Canary 5 I have had issues with Instant Run, it gives me the following error when Instant Run is Enable:

Information:Gradle tasks [:app:assembleDebug]
Error:C:\..etc.\app\build\intermediates\instant-run-support\debug\dependencies\AndroidManifest.xml:2 resource string/app_build_version_name (aka com.itbackyard.iels.client:string/app_build_version_name) not found
Error:java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.AaptException: AAPT2 link failed:
Error:com.android.builder.internal.aapt.AaptException: AAPT2 link failed:
Error:java.lang.RuntimeException: com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: Failed to execute aapt
Error:com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: Failed to execute aapt
Error:com.android.ide.common.process.ProcessException: Failed to execute aapt
Error:java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.AaptException: AAPT2 link failed:
Error:com.android.builder.internal.aapt.AaptException: AAPT2 link failed:
Information:BUILD FAILED in 1m 29s
Information:8 errors
Information:0 warnings
Information:See complete output in console

My only solution was to disable Instant Run from settings. What I was able to find is this topic with out solution so far.

Any idea if this is still a bug or is there any work around till it gets fixed?

Here is my version information:

Android Studio 3.0 Canary 5
Build #AI-171.4141229, built on June 28, 2017
JRE: 1.8.0_152-release-884-b01 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0

Edit
I have now updated to

Android Studio 3.0 Canary 6
Build #AI-171.4163606, built on July 7, 2017
JRE: 1.8.0_152-release-884-b01 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0

And updated to Canary 7

Android Studio 3.0 Canary 7
Build #AI-171.4182969, built on July 14, 2017
JRE: 1.8.0_152-release-884-b01 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0

Still the same problem.

Body:
Add this line gradle.properties file. it work for me

android.enableAapt2=false

Android Studio 3.0 Canary 5

If your build fails due to resource processing issue. To temporarily disable AAPT, set android.enableAapt2=false in your gradle.properties file.


问:
How to use laravel query builder 'when' operator targeting a column of the same result set
Maybe I'm trying to accomplish this in the wrong way but I need to able to insert an if condition inside a laravel query builder:

```<code>$name = $request->input('name');
$query = DB::connection('dbconxz')
            ->table('all_items')->select('name', 'price', 'description', 'type', 'quantity', 'exempt')
            ->where('name', 'like', "%{$name}%")
            ->when('??? how to target the *TYPE* column?'== 'Inventory', function ($query) {
                return $query->where('quantity', '>', 0);
            })
            ->get();
</code>```

I have an ajax auto complete that is searching the table all_items and returning the collection of the items where the name is LIKE what the user is typing.. typical ajax autocomplete from database.  Now my problem is that the column named "type" some of the rows have the word 'Inventory' and I wish to only include that result if the quantity of that row is > 0.

Any ideas?

答:
So let's figure this out with regular SQL.

```<code>SELECT name, price, description, type, quantity, exempt
FROM all_items
WHERE name LIKE %$name%
    AND (
        (
            type = 'Inventory'
            AND quantity > 0
        )
        OR type <> 'Inventory'
    );
</code>```

Then, using Laravel:

```<code>$name = $request->input('name');
$query = DB::connection('dbconxz')
    ->table('all_items')->select('name', 'price', 'description', 'type', 'quantity', 'exempt')
    ->where('name', 'like', "%{$name}%")
    ->where(function ($query) {
        return $query->where([
            'type', '=', 'Inventory',
            'quantity', '>', 0
        ])
        ->orWhere('type', '<>', 'Inventory');
    })
    ->get();
</code>```

Body:
Maybe I'm trying to accomplish this in the wrong way but I need to able to insert an if condition inside a laravel query builder:

$name = $request->input('name');
$query = DB::connection('dbconxz')
            ->table('all_items')->select('name', 'price', 'description', 'type', 'quantity', 'exempt')
            ->where('name', 'like', "%{$name}%")
            ->when('??? how to target the *TYPE* column?'== 'Inventory', function ($query) {
                return $query->where('quantity', '>', 0);
            })
            ->get();

I have an ajax auto complete that is searching the table all_items and returning the collection of the items where the name is LIKE what the user is typing.. typical ajax autocomplete from database.  Now my problem is that the column named "type" some of the rows have the word 'Inventory' and I wish to only include that result if the quantity of that row is > 0.

Any ideas?

Body:
So let's figure this out with regular SQL.

SELECT name, price, description, type, quantity, exempt
FROM all_items
WHERE name LIKE %$name%
    AND (
        (
            type = 'Inventory'
            AND quantity > 0
        )
        OR type <> 'Inventory'
    );

Then, using Laravel:

$name = $request->input('name');
$query = DB::connection('dbconxz')
    ->table('all_items')->select('name', 'price', 'description', 'type', 'quantity', 'exempt')
    ->where('name', 'like', "%{$name}%")
    ->where(function ($query) {
        return $query->where([
            'type', '=', 'Inventory',
            'quantity', '>', 0
        ])
        ->orWhere('type', '<>', 'Inventory');
    })
    ->get();


问:
Access intermediary model values Django
I have a simple question. using the example from django above. How can i get  for example the invite_reason from Person on a Group ? or all joined dates to all groups from that person ? thanks.</p>

```<code>class Person(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)
</code>```

答:
You'll need to query your Membership model for that, like so:

```<code>memberships = Membership.objects.filter(person=person, group=group)
for membership in memberships:
    membership.invite_reason
</code>```

Alternately, you could query it based on the relation:

```<code>memberships = person.membership_set.filter(group=group)
for membership in memberships:
    membership.invite_reason
</code>```

Title: Access intermediary model values Django

Body:
I have a simple question. using the example from django above. How can i get  for example the invite_reason from Person on a Group ? or all joined dates to all groups from that person ? thanks.

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __unicode__(self):
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

Body:
You'll need to query your Membership model for that, like so:

memberships = Membership.objects.filter(person=person, group=group)
for membership in memberships:
    membership.invite_reason

Alternately, you could query it based on the relation:

memberships = person.membership_set.filter(group=group)
for membership in memberships:
    membership.invite_reason


问:
Strange behavior using docker
i'm using neo4j with docker.
At the large, the product is running, but I cannot config it.
I added some configs in a neo4j/conf/neo4j.conf (which are ignored|).

This is my launch command:

```<code>docker run -e NEO4J_dbms_security_procedures_unrestricted=apoc.\\\* --publish=7474:7474 --publish=7687:7687 --volume=$HOME/arianne/2017/neo4j/data:/data --volume=$HOME/arianne/2017/neo4j/logs:/logs --volume=$HOME/arianne/2017/neo4j/conf:/conf --rm -e NEO4J_AUTH=none --volume=$HOME/arianne/2017/neo4j/plugins:/plugins neo4j:3.2
</code>```

and this is the loading log ...

```<code>Active database: graph.db
Directories in use:
  home:         /var/lib/neo4j
  config:       /var/lib/neo4j/conf
  logs:         /logs
  plugins:      /plugins
  import:       /var/lib/neo4j/import
  data:         /var/lib/neo4j/data
  certificates: /var/lib/neo4j/certificates
  run:          /var/lib/neo4j/run
Starting Neo4j.
    2017-07-05 10:18:27.679+0000 WARN  Unknown config option:
causal_clustering.discovery_listen_address
    2017-07-05 10:18:27.681+0000 WARN  Unknown config option:
causal_clustering.raft_advertised_address
    2017-07-05 10:18:27.681+0000 WARN  Unknown config option:
causal_clustering.raft_listen_address
    2017-07-05 10:18:27.681+0000 WARN  Unknown config option:
ha.host.coordination
2017-07-05 10:18:27.681+0000 WARN  Unknown config option:
    causal_clustering.transaction_advertised_address
2017-07-05 10:18:27.682+0000 WARN  Unknown config option:
    causal_clustering.discovery_advertised_address
2017-07-05 10:18:27.682+0000 WARN  Unknown config option: ha.host.data
2017-07-05 10:18:27.682+0000 WARN  Unknown config option:
    causal_clustering.transaction_listen_address
2017-07-05 10:18:27.717+0000 INFO  ======== Neo4j 3.2.1 ========
2017-07-05 10:18:27.918+0000 INFO  No SSL certificate found,
    generating a self-signed certificate..
2017-07-05 10:18:28.759+0000 INFO  Starting...
2017-07-05 10:18:30.433+0000 INFO  Bolt enabled on 0.0.0.0:7687.
2017-07-05 10:18:40.255+0000 INFO  Started.
2017-07-05 10:18:42.441+0000 INFO  Remote interface available at
    http://192.168.10.196:7474/
</code>```

The directory are totally different from those I put on the command line, and the directory var/lib/neo4j doesnt exists!!!

Any idea?
Paolo

答:
This works for me :

```<code>sudo docker run \
-p 7474:7474 \
-p 7687:7687 \
-p 7473:7473 \
-v $HOME/dockerneo4j/data:/data \
-v $HOME/dockerneo4j/logs:/logs \
-v $HOME/dockerneo4j/import:/import \
-v $HOME/dockerneo4j/conf:/conf \
-v $HOME/dockerneo4j/plugins:/plugins \
neo4j:3.2.1
</code>```

The config-file in dockerneo4j/conf is used (easily tested by changing the databasename in there and checking in dockerneo4j/data if a new database folder is created). The apoc plugins are picked up too.

It is correct (although - granted - confusing) that the log shows /var/lib/neo4j directories, those are the internal ones in your docker image.

Hope this helps,
Tom

P.S. http://kvangundy.com/wp/set-up-neo4j-and-docker/ has all the information.

Title: Strange behavior using docker

Body:
i'm using neo4j with docker.
At the large, the product is running, but I cannot config it.
I added some configs in a neo4j/conf/neo4j.conf (which are ignored|).

This is my launch command:

docker run -e NEO4J_dbms_security_procedures_unrestricted=apoc.\\\* --publish=7474:7474 --publish=7687:7687 --volume=$HOME/arianne/2017/neo4j/data:/data --volume=$HOME/arianne/2017/neo4j/logs:/logs --volume=$HOME/arianne/2017/neo4j/conf:/conf --rm -e NEO4J_AUTH=none --volume=$HOME/arianne/2017/neo4j/plugins:/plugins neo4j:3.2

and this is the loading log ...

Active database: graph.db
Directories in use:
  home:         /var/lib/neo4j
  config:       /var/lib/neo4j/conf
  logs:         /logs
  plugins:      /plugins
  import:       /var/lib/neo4j/import
  data:         /var/lib/neo4j/data
  certificates: /var/lib/neo4j/certificates
  run:          /var/lib/neo4j/run
Starting Neo4j.
    2017-07-05 10:18:27.679+0000 WARN  Unknown config option:
causal_clustering.discovery_listen_address
    2017-07-05 10:18:27.681+0000 WARN  Unknown config option:
causal_clustering.raft_advertised_address
    2017-07-05 10:18:27.681+0000 WARN  Unknown config option:
causal_clustering.raft_listen_address
    2017-07-05 10:18:27.681+0000 WARN  Unknown config option:
ha.host.coordination
2017-07-05 10:18:27.681+0000 WARN  Unknown config option:
    causal_clustering.transaction_advertised_address
2017-07-05 10:18:27.682+0000 WARN  Unknown config option:
    causal_clustering.discovery_advertised_address
2017-07-05 10:18:27.682+0000 WARN  Unknown config option: ha.host.data
2017-07-05 10:18:27.682+0000 WARN  Unknown config option:
    causal_clustering.transaction_listen_address
2017-07-05 10:18:27.717+0000 INFO  ======== Neo4j 3.2.1 ========
2017-07-05 10:18:27.918+0000 INFO  No SSL certificate found,
    generating a self-signed certificate..
2017-07-05 10:18:28.759+0000 INFO  Starting...
2017-07-05 10:18:30.433+0000 INFO  Bolt enabled on 0.0.0.0:7687.
2017-07-05 10:18:40.255+0000 INFO  Started.
2017-07-05 10:18:42.441+0000 INFO  Remote interface available at
    http://192.168.10.196:7474/

The directory are totally different from those I put on the command line, and the directory var/lib/neo4j doesnt exists!!!

Any idea?
Paolo

Body:
This works for me :

sudo docker run \
-p 7474:7474 \
-p 7687:7687 \
-p 7473:7473 \
-v $HOME/dockerneo4j/data:/data \
-v $HOME/dockerneo4j/logs:/logs \
-v $HOME/dockerneo4j/import:/import \
-v $HOME/dockerneo4j/conf:/conf \
-v $HOME/dockerneo4j/plugins:/plugins \
neo4j:3.2.1

The config-file in dockerneo4j/conf is used (easily tested by changing the databasename in there and checking in dockerneo4j/data if a new database folder is created). The apoc plugins are picked up too.

It is correct (although - granted - confusing) that the log shows /var/lib/neo4j directories, those are the internal ones in your docker image.

Hope this helps,
Tom

P.S. http://kvangundy.com/wp/set-up-neo4j-and-docker/ has all the information.