问:
Why foreground Service not working after removing app from the background?
I have been trying to implement foreground service to get location after every 3 sec even when the app is in the background by showing a notification. But when I remove my app from the background notification also removes. However, this is only occurring when I am doing it in MI REDMI NOTE 5(API version 28) and MI REDMI NOTE 4(API version 24) but when I ran the same app in Samsung J5(API version 23), the notification is showing even when the app is removed from background until it is manually stopped from the activity. Is the varied result behavior is due to change in API or is it because of different phone model?

Here's my Service Class

```<code>package com.example.locationrunandall;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

public class ForeService extends Service {

    private static final String PACKAGE_NAME =
            "com.example.customizedforeground";

    static final String ACTION_BROADCAST = PACKAGE_NAME + ".broadcast";
    static final String EXTRA_LOCATION = PACKAGE_NAME + ".location";
    private static final String EXTRA_STARTED_FROM_NOTIFICATION = PACKAGE_NAME +
            ".started_from_notification";
    private Handler mServiceHandler;
    private NotificationManager mNotificationManager;
   // private Notification notification;
    private LocationRequest mLocationRequest;
    private FusedLocationProviderClient mFusedLocationClient;
    private LocationCallback mLocationCallback;
    private Location mLocation;
    private static final String CHANNEL_ID = "CHANNEL_ONE";
    private static final int NOTIFICATION_ID = 4567123;
    private static final String TAG = "123";
    String loc;

    public ForeService(){}

    @Override
    public void onCreate() {
      mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
      mLocationCallback = new LocationCallback(){
    @Override
    public void onLocationResult(LocationResult locationResult) {
        super.onLocationResult(locationResult);
      //Do Location Work You Want To Do
        onNewLocation(locationResult.getLastLocation());
    }
};
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(3*1000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        getLastLocation();
        HandlerThread handlerThread = new HandlerThread("HANDLER");
        handlerThread.start();
        mServiceHandler = new Handler(handlerThread.getLooper());
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        CharSequence name = "Name Charseq";
        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
            NotificationChannel notificationChannel = new
                    NotificationChannel(CHANNEL_ID,name, NotificationManager.IMPORTANCE_DEFAULT);

            mNotificationManager.createNotificationChannel(notificationChannel);
        }
        startForeground(NOTIFICATION_ID,getNotification());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
       // startForeground(NOTIFICATION_ID,getNotification());
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceHandler.removeCallbacksAndMessages(null);

        //stopForeground(true);
    }

    @androidx.annotation.Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void getLastLocation() {
        try {
            mFusedLocationClient.getLastLocation()
                    .addOnCompleteListener(new OnCompleteListener<Location>() {
                        @Override
                        public void onComplete(@NonNull Task<Location> task) {
                            if (task.isSuccessful() && task.getResult() != null) {
                                mLocation = task.getResult();
                            } else {
                                Log.d(TAG, "Failed to get location.");
                            }
                        }
                    });
        } catch (SecurityException unlikely) {
            Log.d(TAG, "Lost location permission." + unlikely);
        }
    }

    private void onNewLocation(Location location) {
        mLocation = location;
        if(mLocation==null)
        Log.d("DSK_OPER","Lat: = "+"Not known");
        else
            Log.d("DSK_OPER"," : "+location.getLatitude());
        //send intent to broadcast reciever
        Intent intent = new Intent(ACTION_BROADCAST);
        intent.putExtra(EXTRA_LOCATION, location);
        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
        // todo - Write More code here
        mNotificationManager.notify(NOTIFICATION_ID,getNotification());
    }

    private Notification getNotification() {

        //Intent intent = new Intent(this,MainActivity.class);

        if(mLocation==null)
            loc = "unknown loc";
        else
            loc = String.valueOf(mLocation.getLatitude());

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setContentTitle("Latitude and longitude")
                .setContentText(" = "+loc)
                .setOngoing(true)
                .setPriority(Notification.PRIORITY_HIGH)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setWhen(System.currentTimeMillis());

        // Set the Channel ID for Android O.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId(CHANNEL_ID);
        }
        return builder.build();
    }

}
</code>```

答:
I am using the foreground service for location update after some interval. Foreground service is useful when you wants to update the location if your app is in background but not killed. But this is your responsibility to stop the foreground service when your app is killed. So you just implement the LifeCycleDelegate so that you can start the service when app is in background and stop the service when app is in foreground. and also kill the service when your main activity or HomeActivity is killed.
this is the code for AppLifecycleHandler.

```<code>internal class AppLifecycleHandler(private val lifeCycleDelegate: LifeCycleDelegate) : Application.ActivityLifecycleCallbacks,
    ComponentCallbacks2 {

private var appInForeground = false

override fun onActivityPaused(p0: Activity?) {}

/**
 * app resumed
 */
override fun onActivityResumed(p0: Activity?) {
    if (!appInForeground) {
        appInForeground = true
        lifeCycleDelegate.onAppForegrounded()
    }
}

override fun onActivityStarted(p0: Activity?) {
}

override fun onActivityDestroyed(p0: Activity?) {
}

override fun onActivitySaveInstanceState(p0: Activity?, p1: Bundle?) {
}

override fun onActivityStopped(p0: Activity?) {
}

override fun onActivityCreated(p0: Activity?, p1: Bundle?) {
}

override fun onLowMemory() {}

override fun onConfigurationChanged(p0: Configuration?) {}

/**
 * app sent to background
 */
override fun onTrimMemory(level: Int) {
    if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
        appInForeground = false
        lifeCycleDelegate.onAppBackgrounded()
    }
}
</code>```

Add this method to your application class
     private fun registerLifecycleHandler(lifeCycleHandler: AppLifecycleHandler) {
        registerActivityLifecycleCallbacks(lifeCycleHandler)
        registerComponentCallbacks(lifeCycleHandler)
    }

```<code>override fun getLifecycle(): Lifecycle {
    return mLifecycleRegistry
}
</code>```

implements LifeCycleDelegate in your application class and override the methods

```<code>internal interface LifeCycleDelegate {
fun onAppBackgrounded()
fun onAppForegrounded()
</code>```

}

create app object in application class

```<code>val lifeCycleHandler = AppLifecycleHandler(this)
    registerLifecycleHandler(lifeCycleHandler)
</code>```

Body:
I have been trying to implement foreground service to get location after every 3 sec even when the app is in the background by showing a notification. But when I remove my app from the background notification also removes. However, this is only occurring when I am doing it in MI REDMI NOTE 5(API version 28) and MI REDMI NOTE 4(API version 24) but when I ran the same app in Samsung J5(API version 23), the notification is showing even when the app is removed from background until it is manually stopped from the activity. Is the varied result behavior is due to change in API or is it because of different phone model?

Here's my Service Class

package com.example.locationrunandall;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

public class ForeService extends Service {

    private static final String PACKAGE_NAME =
            "com.example.customizedforeground";

    static final String ACTION_BROADCAST = PACKAGE_NAME + ".broadcast";
    static final String EXTRA_LOCATION = PACKAGE_NAME + ".location";
    private static final String EXTRA_STARTED_FROM_NOTIFICATION = PACKAGE_NAME +
            ".started_from_notification";
    private Handler mServiceHandler;
    private NotificationManager mNotificationManager;
   // private Notification notification;
    private LocationRequest mLocationRequest;
    private FusedLocationProviderClient mFusedLocationClient;
    private LocationCallback mLocationCallback;
    private Location mLocation;
    private static final String CHANNEL_ID = "CHANNEL_ONE";
    private static final int NOTIFICATION_ID = 4567123;
    private static final String TAG = "123";
    String loc;

    public ForeService(){}

    @Override
    public void onCreate() {
      mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
      mLocationCallback = new LocationCallback(){
    @Override
    public void onLocationResult(LocationResult locationResult) {
        super.onLocationResult(locationResult);
      //Do Location Work You Want To Do
        onNewLocation(locationResult.getLastLocation());
    }
};
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(3*1000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        getLastLocation();
        HandlerThread handlerThread = new HandlerThread("HANDLER");
        handlerThread.start();
        mServiceHandler = new Handler(handlerThread.getLooper());
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        CharSequence name = "Name Charseq";
        if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
            NotificationChannel notificationChannel = new
                    NotificationChannel(CHANNEL_ID,name, NotificationManager.IMPORTANCE_DEFAULT);

            mNotificationManager.createNotificationChannel(notificationChannel);
        }
        startForeground(NOTIFICATION_ID,getNotification());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
       // startForeground(NOTIFICATION_ID,getNotification());
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceHandler.removeCallbacksAndMessages(null);

        //stopForeground(true);
    }

    @androidx.annotation.Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void getLastLocation() {
        try {
            mFusedLocationClient.getLastLocation()
                    .addOnCompleteListener(new OnCompleteListener<Location>() {
                        @Override
                        public void onComplete(@NonNull Task<Location> task) {
                            if (task.isSuccessful() && task.getResult() != null) {
                                mLocation = task.getResult();
                            } else {
                                Log.d(TAG, "Failed to get location.");
                            }
                        }
                    });
        } catch (SecurityException unlikely) {
            Log.d(TAG, "Lost location permission." + unlikely);
        }
    }

    private void onNewLocation(Location location) {
        mLocation = location;
        if(mLocation==null)
        Log.d("DSK_OPER","Lat: = "+"Not known");
        else
            Log.d("DSK_OPER"," : "+location.getLatitude());
        //send intent to broadcast reciever
        Intent intent = new Intent(ACTION_BROADCAST);
        intent.putExtra(EXTRA_LOCATION, location);
        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
        // todo - Write More code here
        mNotificationManager.notify(NOTIFICATION_ID,getNotification());
    }

    private Notification getNotification() {

        //Intent intent = new Intent(this,MainActivity.class);

        if(mLocation==null)
            loc = "unknown loc";
        else
            loc = String.valueOf(mLocation.getLatitude());

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setContentTitle("Latitude and longitude")
                .setContentText(" = "+loc)
                .setOngoing(true)
                .setPriority(Notification.PRIORITY_HIGH)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setWhen(System.currentTimeMillis());

        // Set the Channel ID for Android O.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId(CHANNEL_ID);
        }
        return builder.build();
    }

}

Body:
I am using the foreground service for location update after some interval. Foreground service is useful when you wants to update the location if your app is in background but not killed. But this is your responsibility to stop the foreground service when your app is killed. So you just implement the LifeCycleDelegate so that you can start the service when app is in background and stop the service when app is in foreground. and also kill the service when your main activity or HomeActivity is killed.
this is the code for AppLifecycleHandler.

internal class AppLifecycleHandler(private val lifeCycleDelegate: LifeCycleDelegate) : Application.ActivityLifecycleCallbacks,
    ComponentCallbacks2 {

private var appInForeground = false

override fun onActivityPaused(p0: Activity?) {}

/**
 * app resumed
 */
override fun onActivityResumed(p0: Activity?) {
    if (!appInForeground) {
        appInForeground = true
        lifeCycleDelegate.onAppForegrounded()
    }
}

override fun onActivityStarted(p0: Activity?) {
}

override fun onActivityDestroyed(p0: Activity?) {
}

override fun onActivitySaveInstanceState(p0: Activity?, p1: Bundle?) {
}

override fun onActivityStopped(p0: Activity?) {
}

override fun onActivityCreated(p0: Activity?, p1: Bundle?) {
}

override fun onLowMemory() {}

override fun onConfigurationChanged(p0: Configuration?) {}

/**
 * app sent to background
 */
override fun onTrimMemory(level: Int) {
    if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
        appInForeground = false
        lifeCycleDelegate.onAppBackgrounded()
    }
}

Add this method to your application class
     private fun registerLifecycleHandler(lifeCycleHandler: AppLifecycleHandler) {
        registerActivityLifecycleCallbacks(lifeCycleHandler)
        registerComponentCallbacks(lifeCycleHandler)
    }

override fun getLifecycle(): Lifecycle {
    return mLifecycleRegistry
}

implements LifeCycleDelegate in your application class and override the methods

internal interface LifeCycleDelegate {
fun onAppBackgrounded()
fun onAppForegrounded()

}

create app object in application class

val lifeCycleHandler = AppLifecycleHandler(this)
    registerLifecycleHandler(lifeCycleHandler)


来源: stackexchange

问:
Flutter/Dart overwriting File in getApplicationDocumentsDirectory not working immediately
I'm trying to overwrite a file in my apps temporary directory but for some reason the overwrite is not taking effect until I fully hot restart my app.

I'm trying to set my _pickedImage variable to the new changedImage once it has been copied to the directory, however when using setState it is always keeping the first image that was placed into the directory and not overwriting it each time. So when I display the _pickedImage it will always show the first initial image until i fully restart, once i fully restart the app the change is taking place. The reason for wanting to do this is so that users can effectively change the image if they wish. Hope this makes sense any help would be massively appreciated

```<code>var image = await ImagePicker.pickImage(source: source, maxWidth: 800.0);

if (image != null) {

  final Directory extDir = await getApplicationDocumentsDirectory();
  final String dirPath = '${extDir.path}/image';

  if (Directory(dirPath).existsSync()) {
    print('it exists');
    var dir = new Directory(dirPath);
    dir.deleteSync(recursive: true);
    if (Directory(dirPath).existsSync()) {
      print('still exists');
    } else {
      //It is getting in here so seemingly its deleting the orignal directory
      print('does not exist');
    }
  }

  new Directory(dirPath).createSync(recursive: true);
  String path =
      '$dirPath/temporaryImage.jpg';

  File changedImage = image.copySync(path);`

    setState(() {
      //this is where the problem lies
      _pickedImage = changedImage;
    });
</code>```

答:
Cache is the problem. See issue https://github.com/flutter/flutter/issues/24858

From documentation https://api.flutter.dev/flutter/painting/ImageProvider-class.html

ImageProvider uses the global imageCache to cache images.

You can use

```<code>import 'package:flutter/painting.dart'

// to clear specific cache
imageCache.evict(FileImage(processedImage));

// to clear all cache
imageCache.clear();
</code>```

It did not directly solve issue I had, however, it was the key.

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to overwrite a file in my apps temporary directory but for some reason the overwrite is not taking effect until I fully hot restart my app.

I'm trying to set my _pickedImage variable to the new changedImage once it has been copied to the directory, however when using setState it is always keeping the first image that was placed into the directory and not overwriting it each time. So when I display the _pickedImage it will always show the first initial image until i fully restart, once i fully restart the app the change is taking place. The reason for wanting to do this is so that users can effectively change the image if they wish. Hope this makes sense any help would be massively appreciated

var image = await ImagePicker.pickImage(source: source, maxWidth: 800.0);

if (image != null) {

  final Directory extDir = await getApplicationDocumentsDirectory();
  final String dirPath = '${extDir.path}/image';

  if (Directory(dirPath).existsSync()) {
    print('it exists');
    var dir = new Directory(dirPath);
    dir.deleteSync(recursive: true);
    if (Directory(dirPath).existsSync()) {
      print('still exists');
    } else {
      //It is getting in here so seemingly its deleting the orignal directory
      print('does not exist');
    }
  }

  new Directory(dirPath).createSync(recursive: true);
  String path =
      '$dirPath/temporaryImage.jpg';

  File changedImage = image.copySync(path);`

    setState(() {
      //this is where the problem lies
      _pickedImage = changedImage;
    });

Body:
Cache is the problem. See issue https://github.com/flutter/flutter/issues/24858

From documentation https://api.flutter.dev/flutter/painting/ImageProvider-class.html

ImageProvider uses the global imageCache to cache images.

You can use

import 'package:flutter/painting.dart'

// to clear specific cache
imageCache.evict(FileImage(processedImage));

// to clear all cache
imageCache.clear();

It did not directly solve issue I had, however, it was the key.


问:
Call transition animation from RecyclerView Adapter instead of Activity
I have an app with a RecyclerView filled with some cards, with help of a custom RecyclerView (RV) Adapter I made.
I then tried to follow this tutorial in order to add a transition between activities. However, as shown in the tutorial, the animations are called when creating an Intent inside an Activity, and my OnClick code is inside the RVAdapter. This gives me no access to the Activity required on the method

```<code>Intent intent = new Intent(HomeActivity.this, TargetActivity.class);
intent.putExtra(TargetActivity.ID, Contact.CONTACTS[position].getId());
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
        // the context of the activity
        MainActivity.this,

        // For each shared element, add to this method a new Pair item,
        // which contains the reference of the view we are transitioning *from*,
        // and the value of the transitionName attribute
        new Pair<View, String>(view.findViewById(R.id.CONTACT_circle),
                getString(R.string.transition_name_circle)),
        new Pair<View, String>(view.findViewById(R.id.CONTACT_name),
                getString(R.string.transition_name_name)),
        new Pair<View, String>(view.findViewById(R.id.CONTACT_phone),
                getString(R.string.transition_name_phone))
);
ActivityCompat.startActivity(HomeActivity.this, intent, options.toBundle());
</code>```

I tried to pass the Activity Object to the RVAdapter in its constructor method, but it only resulted in NullPointerExceptions.

Here's my RVAdapter code:

```<code>public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.AppVH>{

ArrayList<App> apps;

@Override
public AppVH onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
    return new AppVH(v);
}

@Override
public void onBindViewHolder(AppVH holder, int position) {
    holder.name.setText(apps.get(position).getName());
    holder.artist.setText(apps.get(position).getArtist());
    String p = "";
    if(apps.get(position).getPrice()==0.0) p="Free";
    else p= "$"+apps.get(position).getPrice()+" "+apps.get(position).getCurrency();
    holder.price.setText(p);
    Picasso.with(AppListActivity.context).load(apps.get(position).getUrlImLarge()).into(holder.icon);
}

@Override
public int getItemCount() {
    return apps.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

RecyclerViewAdapter(ArrayList<App> applications){
    this.apps = applications;
}

// Clean all elements of the recycler
public void clear() {
    apps.clear();
    notifyDataSetChanged();
}

// Add a list of items
public void addAll(ArrayList<App> list) {
    apps.addAll(list);
    notifyDataSetChanged();
}

public class AppVH extends RecyclerView.ViewHolder implements View.OnClickListener{

    CardView cv;
    TextView name;
    TextView artist;
    TextView price;
    ImageView icon;
    private final Context c;

    public AppVH(View itemView) {
        super(itemView);
        cv = (CardView) itemView.findViewById(R.id.cardview);
        name = (TextView) itemView.findViewById(R.id.app_name);
        artist = (TextView) itemView.findViewById(R.id.app_artist);
        price = (TextView) itemView.findViewById(R.id.app_price);
        icon = (ImageView) itemView.findViewById(R.id.app_icon);
        itemView.setOnClickListener(this);
        c = itemView.getContext();
    }

    @Override
    public void onClick(View v) {
        final Intent intent;
        Log.d("Debugtext","Card with position " + getAdapterPosition() + " was touched.");
        intent = new Intent(c, AppDetailActivity.class);
        intent.putExtra("app",apps.get(getAdapterPosition()));
        c.startActivity(intent);
    }
}
}
</code>```

Here's how I add the adapter to the RecyclerView in my "HomeActivity".

```<code>RecyclerView rv = (RecyclerView) findViewById(R.id.recycler_view);

    rv.setHasFixedSize(true);
    GridLayoutManager gridlm = new GridLayoutManager(getApplicationContext(),columns);
    rv.setLayoutManager(gridlm);
    rvadapter = new RecyclerViewAdapter(apps);
    rv.setAdapter(rvadapter);
</code>```

Is there an easy way to call the ActivityCompat.startActivity(...) method from within the Adapter?

答:
```<code>ActivityOptions options  = ActivityOptions.makeSceneTransitionAnimation((Activity) mContext);
</code>```

<p>Note: mContext was initialized in the recycler adapter constructor.        </p>

ContentLicense: CC BY-SA 3.0

Body:
I have an app with a RecyclerView filled with some cards, with help of a custom RecyclerView (RV) Adapter I made.
I then tried to follow this tutorial in order to add a transition between activities. However, as shown in the tutorial, the animations are called when creating an Intent inside an Activity, and my OnClick code is inside the RVAdapter. This gives me no access to the Activity required on the method

Intent intent = new Intent(HomeActivity.this, TargetActivity.class);
intent.putExtra(TargetActivity.ID, Contact.CONTACTS[position].getId());
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
        // the context of the activity
        MainActivity.this,

        // For each shared element, add to this method a new Pair item,
        // which contains the reference of the view we are transitioning *from*,
        // and the value of the transitionName attribute
        new Pair<View, String>(view.findViewById(R.id.CONTACT_circle),
                getString(R.string.transition_name_circle)),
        new Pair<View, String>(view.findViewById(R.id.CONTACT_name),
                getString(R.string.transition_name_name)),
        new Pair<View, String>(view.findViewById(R.id.CONTACT_phone),
                getString(R.string.transition_name_phone))
);
ActivityCompat.startActivity(HomeActivity.this, intent, options.toBundle());

I tried to pass the Activity Object to the RVAdapter in its constructor method, but it only resulted in NullPointerExceptions.

Here's my RVAdapter code:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.AppVH>{

ArrayList<App> apps;

@Override
public AppVH onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
    return new AppVH(v);
}

@Override
public void onBindViewHolder(AppVH holder, int position) {
    holder.name.setText(apps.get(position).getName());
    holder.artist.setText(apps.get(position).getArtist());
    String p = "";
    if(apps.get(position).getPrice()==0.0) p="Free";
    else p= "$"+apps.get(position).getPrice()+" "+apps.get(position).getCurrency();
    holder.price.setText(p);
    Picasso.with(AppListActivity.context).load(apps.get(position).getUrlImLarge()).into(holder.icon);
}

@Override
public int getItemCount() {
    return apps.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

RecyclerViewAdapter(ArrayList<App> applications){
    this.apps = applications;
}

// Clean all elements of the recycler
public void clear() {
    apps.clear();
    notifyDataSetChanged();
}

// Add a list of items
public void addAll(ArrayList<App> list) {
    apps.addAll(list);
    notifyDataSetChanged();
}

public class AppVH extends RecyclerView.ViewHolder implements View.OnClickListener{

    CardView cv;
    TextView name;
    TextView artist;
    TextView price;
    ImageView icon;
    private final Context c;

    public AppVH(View itemView) {
        super(itemView);
        cv = (CardView) itemView.findViewById(R.id.cardview);
        name = (TextView) itemView.findViewById(R.id.app_name);
        artist = (TextView) itemView.findViewById(R.id.app_artist);
        price = (TextView) itemView.findViewById(R.id.app_price);
        icon = (ImageView) itemView.findViewById(R.id.app_icon);
        itemView.setOnClickListener(this);
        c = itemView.getContext();
    }

    @Override
    public void onClick(View v) {
        final Intent intent;
        Log.d("Debugtext","Card with position " + getAdapterPosition() + " was touched.");
        intent = new Intent(c, AppDetailActivity.class);
        intent.putExtra("app",apps.get(getAdapterPosition()));
        c.startActivity(intent);
    }
}
}

Here's how I add the adapter to the RecyclerView in my "HomeActivity".

RecyclerView rv = (RecyclerView) findViewById(R.id.recycler_view);

    rv.setHasFixedSize(true);
    GridLayoutManager gridlm = new GridLayoutManager(getApplicationContext(),columns);
    rv.setLayoutManager(gridlm);
    rvadapter = new RecyclerViewAdapter(apps);
    rv.setAdapter(rvadapter);

Is there an easy way to call the ActivityCompat.startActivity(...) method from within the Adapter?

Body:
ActivityOptions options  = ActivityOptions.makeSceneTransitionAnimation((Activity) mContext);

Note: mContext was initialized in the recycler adapter constructor.


问:
how to solve org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
How to solve stale element exception I have already tried with web driver wait and try n catch but still getting the same. It is clicking the button also which I am trying to click in a table and also navigating to next page.

This is the code for the same:

```<code>for(int cnum=1;cnum<=1;cnum++)
                {
                System.out.println("SOURCE_TABLE_ID-> " + columns.get(1).getText() + "\t ||" +"\t SOURCE_TABLE_NAME-> "+ columns.get(2).getText());

                String beforexpath = "//*[@id='root']//table/tbody/tr[";
                String afterxpath = "]/td[3]";

                for (int i=1;i<=rnum;i++)
                {
                    String SourceTableName= driver.findElement(By.xpath(beforexpath+i+afterxpath)).getText();

                    if(SourceTableName.contains("bank_data"))
                    {
                       WebElement sourcetable_element =new WebDriverWait(driver, 70).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id='root']//table/tbody/tr["+i+"]/td[5]/div[@class='glyphicon glyphicon-plus']")));
                        sourcetable_element.click();
                        break;
                        }
                    else
                    {
                        System.out.println("does not starts with B so not clicking");
                    }
</code>```

答:
First of all lets be clear about what a WebElement is.

A WebElement is a reference to a specific element in the DOM.

A StaleElementReferenceException is thrown when the element you were interacting with is destroyed and then recreated resulting in your WebElement (the reference to a specific element in the DOM) becoming stale (i.e. it no longer references anything because the element it did reference has been destroyed).

Most complex web pages these days will move things about on the fly as the user interacts with it and this requires elements in the DOM to be destroyed and recreated causing StaleElementReference errors.  Remember, the element that has been recreated may look identical to the element that was destroyed, so visually the page may look identical when in reality the original element has been destroyed and then recreated.

The only way you can fix a StaleElementReferenceException is to reset your reference to an element in the DOM, this is done by searching for the element again.  So once your WebElement has become stale you need to perform another driver.findElement() to find the element in the DOM again which will reset the reference.

Body:
How to solve stale element exception I have already tried with web driver wait and try n catch but still getting the same. It is clicking the button also which I am trying to click in a table and also navigating to next page.

This is the code for the same:

for(int cnum=1;cnum<=1;cnum++)
                {
                System.out.println("SOURCE_TABLE_ID-> " + columns.get(1).getText() + "\t ||" +"\t SOURCE_TABLE_NAME-> "+ columns.get(2).getText());

                String beforexpath = "//*[@id='root']//table/tbody/tr[";
                String afterxpath = "]/td[3]";

                for (int i=1;i<=rnum;i++)
                {
                    String SourceTableName= driver.findElement(By.xpath(beforexpath+i+afterxpath)).getText();

                    if(SourceTableName.contains("bank_data"))
                    {
                       WebElement sourcetable_element =new WebDriverWait(driver, 70).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id='root']//table/tbody/tr["+i+"]/td[5]/div[@class='glyphicon glyphicon-plus']")));
                        sourcetable_element.click();
                        break;
                        }
                    else
                    {
                        System.out.println("does not starts with B so not clicking");
                    }


问:
Python-How to add a struct.pack value to an integer that would be sent through the serial port
I'm a newbie in python and recently I made a similar question about how to convert a decimal value to an integer with low byte first and then high byte is here and is solved but now I have a problem because I want python to take a decimal value from a raw_input convert it to an integer with low byte first and then high byte and insert it into a 16-bit integer to send it to the serial port to a servo controller (devantech sd84). I've contained the raw_input into a value and then the struc.pack in other value then I put the second value into the 16-bit integer but before this can occurs python returns this error:

```<code>    Traceback (most recent call last):
    File "C:/Users/Pablo/Desktop/kdfkldkfgv", line 28, in <module>
    POS_SERVO = struct.pack('<h', 'posicion')
    error: cannot convert argument to integer
</code>```

Here is the complete code:

```<code>    # -*- coding: utf-8 -*-
  import serial
  import time
  import struct
  # Para cambiar de Sistema Operativo cambiar puerto
  #en la siguiente línea: Win COM# linux /dev/ttyS# /dev/ttyUSB#
  # #=un número asignado por tu sistema.
  port='COM3'
  sync='\xAA\xA0\x55'
  SET_SERVO='\x01'
  GET_SERVO='\x02'
  SET_SPEED='\x03'
  SET_MODE='\x04'
  GET_MODE='\x05'
  SET_AD_CNT='\x06' #Controla el número de canales analógicos.
  GET_AD_CNT='\x07' #Devuelve el número de canales analógicos actuales.
  GET_INPUT='\X08' # Devuelve el estado de una entrada.
  GET_ADC='\X09' #Devuelve el valor de un canal analógico.
  GET_VERSION='\x0A' #Devuelve la versión del procesador seleccionado.
  GET_BULK='\x15' #Usado para test en fábriica.
  TEST='\X16' #Usado para test en fábrica.
  ser = serial.Serial(port, baudrate=115200, bytesize=8, parity='N', stopbits=2,timeout=1)

  if ser.isOpen():
print "Estado del puerto: Correcto."
print "Procedo a enviar modo del canal 1 y posiciones del mismo."
posicion = raw_input('Inserta un numero entre 400 y 2200:')
POS_SERVO = struct.pack('<h', 'posicion')
ser.write(sync+SET_MODE+'\x01\x01\x19')
ser.write(sync+SET_SERVO+'\x01\x02'+POS_SERVO)
time.sleep(1.6)
ser.close
print "Todo el proceso completado correctamente."

   else:
print "El puertito está cerrado"

   print "Hasta Luego :D"
</code>```

For the interest of people who have the same controler I'll explain that 16-bit integer first three bytes are sync (\xAA\xA0\x55) then the type of command SET_SERVO (position) (\x01) then the channel 1-84 for 1 is (\x01) then a byte count in this case 2 (\x02) and the servo position low byte and then the high byte (POS_SERVO) (for example for 1500 \xDC\x05)

I don't know how to solve it, because it's not an argument in fact it is a value and I don't know how to tell that to python.

答: In my case I searched a lot around to find the problem. Pass ints arguments to struct.pack instead of strings!

Body:
I'm a newbie in python and recently I made a similar question about how to convert a decimal value to an integer with low byte first and then high byte is here and is solved but now I have a problem because I want python to take a decimal value from a raw_input convert it to an integer with low byte first and then high byte and insert it into a 16-bit integer to send it to the serial port to a servo controller (devantech sd84). I've contained the raw_input into a value and then the struc.pack in other value then I put the second value into the 16-bit integer but before this can occurs python returns this error:

    Traceback (most recent call last):
    File "C:/Users/Pablo/Desktop/kdfkldkfgv", line 28, in <module>
    POS_SERVO = struct.pack('<h', 'posicion')
    error: cannot convert argument to integer

Here is the complete code:

    # -*- coding: utf-8 -*-
  import serial
  import time
  import struct
  # Para cambiar de Sistema Operativo cambiar puerto
  #en la siguiente línea: Win COM# linux /dev/ttyS# /dev/ttyUSB#
  # #=un número asignado por tu sistema.
  port='COM3'
  sync='\xAA\xA0\x55'
  SET_SERVO='\x01'
  GET_SERVO='\x02'
  SET_SPEED='\x03'
  SET_MODE='\x04'
  GET_MODE='\x05'
  SET_AD_CNT='\x06' #Controla el número de canales analógicos.
  GET_AD_CNT='\x07' #Devuelve el número de canales analógicos actuales.
  GET_INPUT='\X08' # Devuelve el estado de una entrada.
  GET_ADC='\X09' #Devuelve el valor de un canal analógico.
  GET_VERSION='\x0A' #Devuelve la versión del procesador seleccionado.
  GET_BULK='\x15' #Usado para test en fábriica.
  TEST='\X16' #Usado para test en fábrica.
  ser = serial.Serial(port, baudrate=115200, bytesize=8, parity='N', stopbits=2,timeout=1)

  if ser.isOpen():
print "Estado del puerto: Correcto."
print "Procedo a enviar modo del canal 1 y posiciones del mismo."
posicion = raw_input('Inserta un numero entre 400 y 2200:')
POS_SERVO = struct.pack('<h', 'posicion')
ser.write(sync+SET_MODE+'\x01\x01\x19')
ser.write(sync+SET_SERVO+'\x01\x02'+POS_SERVO)
time.sleep(1.6)
ser.close
print "Todo el proceso completado correctamente."

   else:
print "El puertito está cerrado"

   print "Hasta Luego :D"

For the interest of people who have the same controler I'll explain that 16-bit integer first three bytes are sync (\xAA\xA0\x55) then the type of command SET_SERVO (position) (\x01) then the channel 1-84 for 1 is (\x01) then a byte count in this case 2 (\x02) and the servo position low byte and then the high byte (POS_SERVO) (for example for 1500 \xDC\x05)

I don't know how to solve it, because it's not an argument in fact it is a value and I don't know how to tell that to python.


问:
Importing JSON from a server within Angular
I am reading data from a JSON, which is one a server and it updates regularly and changes. I need to be able to read this JSON from the server so that I display the most up to date information on my web page.

Currently, the to be able to read the JSONs they are stored within the same project folder as my angular project. (This was because they were not set up on the server when I started).

This is how I currently import the JSON to be able to read it:

```<code>import jsonInfo from '../../../info.json'
</code>```

I thought I would be able to change the file link to the server address, like so:

```<code>import jsonInfo from 'http://servername/folder/info.json'
</code>```

But, VSCode gives me an error: Cannot find module 'http://servername/folder/info.json'

This is definitely the location of the JSON I am trying to load because when I click the link it takes me to the JSON and displays it.

My question is, how do I import the JSON into my .ts from a server so that I can keep getting the updated information from the JSON?

答:
You can use HttpClient and do like as shown below

Working Demo

```<code>import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {

  name = 'Angular';
  data = [];

  apiUrl = 'http://servername/folder/info.json';

  GetData() {
    this.http.get<any[]>(this.apiUrl)
      .subscribe(data => {
        this.data = data;
      });
  }

  ClearData() {
    this.data = [];
  }

  constructor(private http: HttpClient) {}
  ngOnInit() {}

}
</code>```

Body:
I am reading data from a JSON, which is one a server and it updates regularly and changes. I need to be able to read this JSON from the server so that I display the most up to date information on my web page.

Currently, the to be able to read the JSONs they are stored within the same project folder as my angular project. (This was because they were not set up on the server when I started).

This is how I currently import the JSON to be able to read it:

import jsonInfo from '../../../info.json'

I thought I would be able to change the file link to the server address, like so:

import jsonInfo from 'http://servername/folder/info.json'

But, VSCode gives me an error: Cannot find module 'http://servername/folder/info.json'

This is definitely the location of the JSON I am trying to load because when I click the link it takes me to the JSON and displays it.

My question is, how do I import the JSON into my .ts from a server so that I can keep getting the updated information from the JSON?

Body:
You can use HttpClient and do like as shown below

Working Demo

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {

  name = 'Angular';
  data = [];

  apiUrl = 'http://servername/folder/info.json';

  GetData() {
    this.http.get<any[]>(this.apiUrl)
      .subscribe(data => {
        this.data = data;
      });
  }

  ClearData() {
    this.data = [];
  }

  constructor(private http: HttpClient) {}
  ngOnInit() {}

}


问:
What is the Diamond Problem in Python and why its not appear in python2?
I got this code:

```<code>class A:
 pass

class B(A):
 pass

class C(A):
 pass

class D(A,B):
 pass

d = D()
</code>```

In Python3 i get a MRO Error. I mean it appears because the Diamond Problem. In Python2 its no Problem. Why is this the case, and what is this Diamond Problem exactly ?

答:
This is not the diamond problem!

The diamond problem occurs when two classes have a common ancestor, and another class has both those classes as base classes, for example:

```<code>class A:
    def do_thing(self):
        print('From A')

class B(A):
    def do_thing(self):
        print('From B')

class C(A):
    def do_thing(self):
        print('From C')

class D(B, C):
    pass

d = D()
d.do_thing()
</code>```

In some languages, because of how inheritance is implemented, when you call d.do_thing(), it is ambiguous whether you actually want the overridden do_thing from B, or the one from C.

Python doesn't have this problem because of the method resolution order. Briefly, when you inherit from multiple classes, if their method names conflict, the first one named takes precedence. Since we have specified D(B, C), B.do_thing is called before C.do_thing.

That is also why you get that problem. Consider this: since B inherits from A in your example, B's methods will come before A's. Say we have another class, B_derived, that inherits from B. The method resolution order will then be as follows:

```<code>B_derived -> B -> A
</code>```

Now, we have D in the place of B_derived, therefore we can substitute it in to get this:

```<code>D -> B -> A
</code>```

However, note that you have also specified that D inherits from A before B, and by the rule above, A must also come before B in the method resolution order. That means we get an inconsistent chain:

```<code>D -> A -> B -> A
</code>```

This, and not the diamond problem, is why you get an error.

(See also this answer).

Body:
I got this code:

class A:
 pass

class B(A):
 pass

class C(A):
 pass

class D(A,B):
 pass

d = D()

In Python3 i get a MRO Error. I mean it appears because the Diamond Problem. In Python2 its no Problem. Why is this the case, and what is this Diamond Problem exactly ?

Body:
This is not the diamond problem!

The diamond problem occurs when two classes have a common ancestor, and another class has both those classes as base classes, for example:

class A:
    def do_thing(self):
        print('From A')

class B(A):
    def do_thing(self):
        print('From B')

class C(A):
    def do_thing(self):
        print('From C')

class D(B, C):
    pass

d = D()
d.do_thing()

In some languages, because of how inheritance is implemented, when you call d.do_thing(), it is ambiguous whether you actually want the overridden do_thing from B, or the one from C.

Python doesn't have this problem because of the method resolution order. Briefly, when you inherit from multiple classes, if their method names conflict, the first one named takes precedence. Since we have specified D(B, C), B.do_thing is called before C.do_thing.

That is also why you get that problem. Consider this: since B inherits from A in your example, B's methods will come before A's. Say we have another class, B_derived, that inherits from B. The method resolution order will then be as follows:

B_derived -> B -> A

Now, we have D in the place of B_derived, therefore we can substitute it in to get this:

D -> B -> A

However, note that you have also specified that D inherits from A before B, and by the rule above, A must also come before B in the method resolution order. That means we get an inconsistent chain:

D -> A -> B -> A

This, and not the diamond problem, is why you get an error.

(See also this answer).


问:
Android How to remove Empty Space
I want to remove empty space. For example: rama chan dran should become ramachandran.

答:
This is more of a Java question than Android specific, but have a look at:

public String replaceAll(String regex, String replacement)

Title: Android How to remove Empty Space


问:
Firestore database rule works in simulator, but not in app
I'm building out a React Native application and just starting to build out all of the security rules in my Firestore database. I have several rules that are working well, but there's one rule that's pretty much identical to the working ones that's giving me
Error: Missing or insufficient permissions.
What's even weirder is that when I test this rule in the Firestore simulator, it passes without any issues.

I've tried shoving all of the conditional logic from the functions into the rule itself, but that did nothing.

Here are the relevant rules:

```<code>service cloud.firestore {
  match /databases/{database}/documents {
    function getCurrentTeam() {
        return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.lastTeam;
    }

    function signedIntoTeam() {
      // For context, all "like" documents have an associated teamId.
      return request.auth.uid != null && getCurrentTeam() == resource.data.teamId;
    }

    match /likes/{like} {
      allow read: if signedIntoTeam();
    }

  }
}
</code>```

Here's the function in my React Native app that's erroring out:

```<code>const getLikes = posts =>
    new Promise((resolve, reject) => {
        const likedPosts = [];
        if (!posts.length) return resolve(likedPosts);
        posts.forEach(post => {
            if (post.likeCount > 0) {
                firebase
                    .firestore()
                    .collection('likes')
                    .where('postId', '==', post.id)
                    .where('userId', '==', firebase.auth().currentUser.uid)
                    .get()
                    .then(querySnapshot => {
                        const likedByUser = querySnapshot.size > 0;
                        likedPosts.push({ ...post, likedByUser });
                        if (likedPosts.length === posts.length) resolve(likedPosts);
                    })
                    .catch(err => reject(err));
            } else {
                likedPosts.push({ ...post, likedByUser: false });
                if (likedPosts.length === posts.length) resolve(likedPosts);
            }
        });
    });
</code>```

I have very similar functions and rules that work fine elsewhere. I just can't seem to figure out why this one in particular is failing.

答:
Your rule is attempting to filter documents from the likes collection based on the contents of the document's teamId field.  If your query does not also filter using this same criteria, the rule will always reject the request.  This is because security rules are not filters.  Please read the linked documentation.

With the rule you have in place, the client is always going to have to filter on the teamId field.  Right now, it is just filtering on postId and userId.  You should add teamId to that, or change the rule to match the query.  The query and the rule need to be in sync - the query must only request documents that is knows to be readable by the rule - it should not rely on the rule to make changes to the result set.

Body:
I'm building out a React Native application and just starting to build out all of the security rules in my Firestore database. I have several rules that are working well, but there's one rule that's pretty much identical to the working ones that's giving me
Error: Missing or insufficient permissions.
What's even weirder is that when I test this rule in the Firestore simulator, it passes without any issues.

I've tried shoving all of the conditional logic from the functions into the rule itself, but that did nothing.

Here are the relevant rules:

service cloud.firestore {
  match /databases/{database}/documents {
    function getCurrentTeam() {
        return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.lastTeam;
    }

    function signedIntoTeam() {
      // For context, all "like" documents have an associated teamId.
      return request.auth.uid != null && getCurrentTeam() == resource.data.teamId;
    }

    match /likes/{like} {
      allow read: if signedIntoTeam();
    }

  }
}

Here's the function in my React Native app that's erroring out:

const getLikes = posts =>
    new Promise((resolve, reject) => {
        const likedPosts = [];
        if (!posts.length) return resolve(likedPosts);
        posts.forEach(post => {
            if (post.likeCount > 0) {
                firebase
                    .firestore()
                    .collection('likes')
                    .where('postId', '==', post.id)
                    .where('userId', '==', firebase.auth().currentUser.uid)
                    .get()
                    .then(querySnapshot => {
                        const likedByUser = querySnapshot.size > 0;
                        likedPosts.push({ ...post, likedByUser });
                        if (likedPosts.length === posts.length) resolve(likedPosts);
                    })
                    .catch(err => reject(err));
            } else {
                likedPosts.push({ ...post, likedByUser: false });
                if (likedPosts.length === posts.length) resolve(likedPosts);
            }
        });
    });

I have very similar functions and rules that work fine elsewhere. I just can't seem to figure out why this one in particular is failing.


问:
Remove HTML paragraph using removeChild
I wrote a code like below:

```<code>     <input type="button" value="remove" onclick="remove()"/>

     <p id="p2">
        before hr
        <hr/>
        after hr
     </p>

  <script>
     function remove() {
        var p = document.getElementById('p2');
        p.parentNode.removeChild(p);
     }
  </script>
</code>```

When I hit the button, only "before hr" disappear - hr and "after hr" text don't.

If I change
 to
 :

```<code><div id="p2">
    before hr
    <hr/>
    after hr
 </div>
</code>```

everything works properly (i.e. like I supposed it should works ;) )

Could somebody explain me the reasons, please?

答:
From the MDN web docs on
:

and notably will automatically close if another block-level element is parsed before the closing
 tag.

And the W3C list of block elements states that
 is a block element.

So your code is evaluated like this:

```<code><p id="p2">
  before hr
</p>
<hr />
<p id="p2">
  after hr
</p>
</code>```

Which is why removing a single child isn't working. Since the ID isn't re-created, the only solution is to change the element type - a
 works fine:

function remove() {
  var p2 = document.getElementById("p2");
  p2.parentNode.removeChild(p2);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><input type="button" value="remove" onclick="remove()" />

<div id="p2">
  before hr
  <hr/> after hr
</div></code>```

Title: Remove HTML paragraph using removeChild

Body:
I wrote a code like below:

     <input type="button" value="remove" onclick="remove()"/>

        before hr

        after hr

When I hit the button, only "before hr" disappear - hr and "after hr" text don't.

If I change
 to
 :

    before hr

    after hr

everything works properly (i.e. like I supposed it should works ;) )

Could somebody explain me the reasons, please?

Body:
From the MDN web docs on <p>:

and notably will automatically close if another block-level element is parsed before the closing </p> tag.

And the W3C list of block elements states that <hr> is a block element.

So your code is evaluated like this:

<p id="p2">
  before hr
</p>
<hr />
<p id="p2">
  after hr
</p>

Which is why removing a single child isn't working. Since the ID isn't re-created, the only solution is to change the element type - a <div> works fine:

function remove() {
  var p2 = document.getElementById("p2");
  p2.parentNode.removeChild(p2);
}

<input type="button" value="remove" onclick="remove()" />

<div id="p2">
  before hr
  <hr/> after hr
</div>


问:
SuppressWarnings("deprecation") for one line in java
I am working with threads and using thread.stop(); to end a thread for a temporary solution to a problem I was having. I understand that it is deprecated and should not be used, but how do I suppress the compiler warning for that one line only? I want to continue getting deprecated warnings for the rest of my class, just not that one line. I tried using the code below and got the error "Annotations are not allowed here" on the @SupressWarnings("deprecation") line. What is the correct way to suppress this error?

class Handeler {
   private Thread thread;
   .....
   void stopThread() {
      if(thread!=null && thread.isAlive()) {
         @SuppressWarnings("deprecation")
            thread.stop();
      }
   }
}
```

答:
You could suppress warning using comment:</p>

```<code>void stopThread() {
      if(thread!=null && thread.isAlive()) {

          //noinspection deprecation
          thread.stop();
      }
}
</code>```

Body:
You could suppress warning using comment:

void stopThread() {
      if(thread!=null && thread.isAlive()) {

          //noinspection deprecation
          thread.stop();
      }
}


问:
Unable to display the current status of a process in VB.Net
I have written below piece of code to achieve my task of exporting printers details on the machine. Below code works without any issues.

Generally, it takes a few seconds or more to generate the printer details file, hence I would like to display the status of this process on a label or text box (like "File is being generated. Please wait..", "File is generated.." etc.)

I'm unable to get the right status on the label with below code. It directly shows the "File is generated" status. But if put messagebox before and after while loop then it works fine.

Any assistance is greatly helpful. Thank you.

```<code>Label1.Text = "Status: File is being generated. Please wait.."

Dim pPrintBrm As New ProcessStartInfo
pPrintBrm.FileName = "C:\Windows\System32\spool\tools\PrintBrm.exe"
pPrintBrm.Arguments = " " & "-B" & " " & "-F" & " " &
My.Computer.FileSystem.CurrentDirectory & "\Extracted\Printer.PrinterExport"
pPrintBrm.WindowStyle = ProcessWindowStyle.Hidden
Process.Start(pPrintBrm)

Dim exists As Boolean = File.Exists(My.Computer.FileSystem.CurrentDirectory & "\Extracted\Printer.PrinterExport")

MessageBox.Show("before while " & exists)

While (exists = "False")

exists = File.Exists(My.Computer.FileSystem.CurrentDirectory & "\Extracted\Printer.PrinterExport")

End While

MessageBox.Show("after while " & exists)

If File.Exists(My.Computer.FileSystem.CurrentDirectory & "\Extracted\Printer.PrinterExport") Then

Label1.Text = "Status: File is generated"
Else
Label1.Text = "Status: Failed"
End If
</code>```

答: Use BackgroundWorker component then do this code in DoWork event of Background Worker and show all update status on the label by BackgroundWorker.ReportProgress()</p>

Body:
I have written below piece of code to achieve my task of exporting printers details on the machine. Below code works without any issues.

Generally, it takes a few seconds or more to generate the printer details file, hence I would like to display the status of this process on a label or text box (like "File is being generated. Please wait..", "File is generated.." etc.)

I'm unable to get the right status on the label with below code. It directly shows the "File is generated" status. But if put messagebox before and after while loop then it works fine.

Any assistance is greatly helpful. Thank you.

Label1.Text = "Status: File is being generated. Please wait.."

Dim pPrintBrm As New ProcessStartInfo
pPrintBrm.FileName = "C:\Windows\System32\spool\tools\PrintBrm.exe"
pPrintBrm.Arguments = " " & "-B" & " " & "-F" & " " &
My.Computer.FileSystem.CurrentDirectory & "\Extracted\Printer.PrinterExport"
pPrintBrm.WindowStyle = ProcessWindowStyle.Hidden
Process.Start(pPrintBrm)

Dim exists As Boolean = File.Exists(My.Computer.FileSystem.CurrentDirectory & "\Extracted\Printer.PrinterExport")

MessageBox.Show("before while " & exists)

While (exists = "False")

exists = File.Exists(My.Computer.FileSystem.CurrentDirectory & "\Extracted\Printer.PrinterExport")

End While

MessageBox.Show("after while " & exists)

If File.Exists(My.Computer.FileSystem.CurrentDirectory & "\Extracted\Printer.PrinterExport") Then

Label1.Text = "Status: File is generated"
Else
Label1.Text = "Status: Failed"
End If


问:
Absolute Block Nested in Relative Block Appears Lower in IE8
Ugh. I really, really hate cross-browser compatibility... I'm working on a Wordpress site for a client to create a popup box that appears just below the item I'm hovering over (using a custom shortcode). I have top set to 16px, and it works fine in Firefox. However, in IE8, it appears a lot further down. Even if I set top to "0", it still appears BELOW the containing blog, instead of at the top of it.

I also have a related issue, in that the font size in IE8 is about 2 pixels smaller. There is a  tag before this, as well, but removing it doesn't change much--the font size is still smaller in IE8.

Here is the page:

http://www.medicalmarcom.com/services/

Every question mark along the left side has a popup that appears when hovering over it (kinda like a tooltip). I need to make it work in FF, IE, Safari, and Chrome. The only one it doesn't work in is IE. Thankfully, he didn't mention IE6, so I'm not worrying about it unless he singles it out.

Here is the HTML:

```<code><span class="questions"><sup>(
<div class="popup_content"><span class="popup">?</span>
<div class="popup_inside" style="display: none;">We’ll ask questions to understand your business, objectives, competitive situation, and positioning statement.<br />

<a href="http://www.medicalmarcom.com/services/medical-device-marketing-discovery/"><span style="color:#15398c"><em>Read More >>></em></span></a></div>
</div>
)</sup></span>
</code>```

CSS:

```<code>.popup_content {
    display: inline;
    position: relative;
}
.popup_inside {
    background-color: #FFF;
    border: 1px solid #000;
    text-align: left;
    font-size: 12px;
    color: #000;
    width: 300px;
    padding: 2px;
    line-height: 1.5;
    left: 0;
    top: 16px;
    z-index: 1001;
    position: absolute;
    display: none;
}
.popup {
    position: relative;
    z-index: 1000;
}
</code>```

答:
Ok, this is due to how ie8 is rendering the sup tag, I believe. It considers its baseline the same as the rest of the text, rather than above it. If you want to do this with just css, I'd consider rolling your own superscript class.

Here's a fiddle of something that seemed to work for me.

As an alternative solution, it seems to be rendering correctly in IE7, you could force IE8 into IE7 Compatibility Mode. Drop this line at the top of your . I don't know what this will do to IE9, but it's worth a shot.

```<code><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
</code>```

Body:
Ugh. I really, really hate cross-browser compatibility... I'm working on a Wordpress site for a client to create a popup box that appears just below the item I'm hovering over (using a custom shortcode). I have top set to 16px, and it works fine in Firefox. However, in IE8, it appears a lot further down. Even if I set top to "0", it still appears BELOW the containing blog, instead of at the top of it.

I also have a related issue, in that the font size in IE8 is about 2 pixels smaller. There is a  tag before this, as well, but removing it doesn't change much--the font size is still smaller in IE8.

Here is the page:

http://www.medicalmarcom.com/services/

Every question mark along the left side has a popup that appears when hovering over it (kinda like a tooltip). I need to make it work in FF, IE, Safari, and Chrome. The only one it doesn't work in is IE. Thankfully, he didn't mention IE6, so I'm not worrying about it unless he singles it out.

Here is the HTML:

(

?

We’ll ask questions to understand your business, objectives, competitive situation, and positioning statement.

Read More >>>

)

CSS:

.popup_content {
    display: inline;
    position: relative;
}
.popup_inside {
    background-color: #FFF;
    border: 1px solid #000;
    text-align: left;
    font-size: 12px;
    color: #000;
    width: 300px;
    padding: 2px;
    line-height: 1.5;
    left: 0;
    top: 16px;
    z-index: 1001;
    position: absolute;
    display: none;
}
.popup {
    position: relative;
    z-index: 1000;
}

Body:
Ok, this is due to how ie8 is rendering the sup tag, I believe. It considers its baseline the same as the rest of the text, rather than above it. If you want to do this with just css, I'd consider rolling your own superscript class.

Here's a fiddle of something that seemed to work for me.

As an alternative solution, it seems to be rendering correctly in IE7, you could force IE8 into IE7 Compatibility Mode. Drop this line at the top of your <head>. I don't know what this will do to IE9, but it's worth a shot.

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />


问:
How to know when text is copied from a specific textfield in Objective-C?
I have some textFields which are editable. when user selects its text copy and paste menu items are shown.

I want to know when user taps on the copy. because I want to change the copied text.

Is it possible?

More details:
I want to change the copy of 3 textfields. I want to concatenate all these 3 textfields texts into clipboard when one of the textfields are copied. There are other textfields in this page too but I don't want to do anything for them.

答:
You can implement the copy() method to "intercept" the copy operation and modify what gets placed on the clipboard.

Easiest way is probably a simple subclass of UITextField:

```<code>//
//  MyTextField.h
//
//  Created by Don Mag on 5/29/19.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyTextField : UITextField

@end

NS_ASSUME_NONNULL_END
</code>```

and

```<code>//
//  MyTextField.m
//
//  Created by Don Mag on 5/29/19.
//

#import "MyTextField.h"

@implementation MyTextField

- (void)copy:(id)sender {

    // debugging
    NSLog(@"copy command selected");

    // get the selected range
    UITextRange *textRange = [self selectedTextRange];

    // if text was selected
    if (textRange) {

        // get the selected text
        NSString *selectedText = [self textInRange:textRange];

        // change it how you want
        NSString *modifiedText = [NSString stringWithFormat:@"Prepending to copied text: %@", selectedText];

        // get the general pasteboard
        UIPasteboard *pb = [UIPasteboard generalPasteboard];

        // set the modified copied text to the pasteboard
        pb.string = modifiedText;
    }

}

@end
</code>```

Body:
You can implement the copy() method to "intercept" the copy operation and modify what gets placed on the clipboard.

Easiest way is probably a simple subclass of UITextField:

//
//  MyTextField.h
//
//  Created by Don Mag on 5/29/19.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyTextField : UITextField

@end

NS_ASSUME_NONNULL_END

and

//
//  MyTextField.m
//
//  Created by Don Mag on 5/29/19.
//

#import "MyTextField.h"

@implementation MyTextField

- (void)copy:(id)sender {

    // debugging
    NSLog(@"copy command selected");

    // get the selected range
    UITextRange *textRange = [self selectedTextRange];

    // if text was selected
    if (textRange) {

        // get the selected text
        NSString *selectedText = [self textInRange:textRange];

        // change it how you want
        NSString *modifiedText = [NSString stringWithFormat:@"Prepending to copied text: %@", selectedText];

        // get the general pasteboard
        UIPasteboard *pb = [UIPasteboard generalPasteboard];

        // set the modified copied text to the pasteboard
        pb.string = modifiedText;
    }

}

@end


问:
Fetching more data from binance using python loop
I am trying to fetch more than 500 rows of historical data from Binance website but I want more than 500 rows, how do i loop through it and fetch more?

The code i tried:

```<code>candles= client.get_klines(symbol='ADABTC',interval=Client.KLINE_INTERVAL_1MINUTE)
    candles_data_frame=df(candles)
</code>```

This code fetches 500 rows but i would expect more than 10000 rows of historical data. Please let me know how should i get it.

Thanks

答: Add the startTime parameter to /api/v1/klines call. Decrease it with each iteration by chosen interval and concat the results into one common array.</p>

Body:
I am trying to fetch more than 500 rows of historical data from Binance website but I want more than 500 rows, how do i loop through it and fetch more?

The code i tried:

candles= client.get_klines(symbol='ADABTC',interval=Client.KLINE_INTERVAL_1MINUTE)
    candles_data_frame=df(candles)

This code fetches 500 rows but i would expect more than 10000 rows of historical data. Please let me know how should i get it.

Thanks


问:
Detect if a page is within a iframe - serverside
How can I detect server-side (c#, asp.net mvc) if the loaded page is within a iframe? Thanks</p>

答:
Old question but why not a more simplistic approach like</p>

```<code>var isFramed = self !== parent
</code>```

ContentLicense: CC BY-SA 2.5

Body:
Old question but why not a more simplistic approach like

var isFramed = self !== parent


问:
Cannot load Bootstrap from local folder using Jersey 2 on Glassfish 4
I'm trying to add Bootstrap to an existing Jersey 2/JSP sample project, using this tutorial as a guide. However, in Chrome console I keep getting 404 errors for Bootstrap's CSS, and the styles won't be loaded.

I tried adding a property in my ResourceConfig:

```<code>property(ServletProperties.FILTER_STATIC_CONTENT_REGEX,
            // "/(images|css)/.*");
            "/css/*")
</code>```

to no avail.

Here's my custom ResourceConfig

```<code>package com.xxx.jersey2.config;

import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.mvc.jsp.JspMvcFeature;
import org.glassfish.jersey.servlet.ServletProperties;

public class CustomResourceConfig extends ResourceConfig {
    public CustomResourceConfig() {
        packages("com.xxx");
        register(LoggingFilter.class);
        register(JspMvcFeature.class);
        // it may be also jersey.config.server.mvc.templateBasePath
        // property("jersey.config.server.mvc.templateBasePath", "/WEB-INF/jsp");
        property(JspMvcFeature.TEMPLATE_BASE_PATH, "/WEB-INF/jsp");
        // CSS and JS
        // property(ServletProperties.FILTER_STATIC_CONTENT_REGEX, "/(static|(WEB-INF/css))/");
        property(ServletProperties.FILTER_STATIC_CONTENT_REGEX,
                // "/(images|css)/.*");
                "/css/*");
    }
}
</code>```

My web.xml

```<code><web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

  <!--<display-name>Archetype Created Web Application</display-name>-->

  <filter>
    <filter-name>jersey</filter-name>
    <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
    <!--
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.xxx.sample-jersey2</param-value>
    </init-param>
    -->
    <init-param>
      <param-name>jersey.config.servlet.filter.forwardOn404</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>com.xxx.jersey2.config.CustomResourceConfig</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>jersey</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!--<welcome-file-list>-->
    <!--<welcome-file>index.html</welcome-file>-->
    <!--<welcome-file>index.htm</welcome-file>-->
    <!--<welcome-file>movies.jsp</welcome-file>-->
  <!--</welcome-file-list>-->

</web-app>
</code>```

My JSP

```<code><%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>Sandbox application</title>
    <link rel="stylesheet" href="../../css/bootstrap.min.css">
    <!-- <script src="../js/bootstrap.min.js"></script> -->

    <!-- Latest compiled and minified CSS -->
    <!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"> -->

    <!-- Optional theme -->
    <!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous"> -->

    <!-- Latest compiled and minified JavaScript -->
    <!-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script> -->
</head>
<body>
<h2>Listing Movies</h2>
    <table class="table table-striped">
        <tr>
            <th>Name</th>
            <th>Starring</th>
        </tr>
        <c:forEach var="item" items="${it.movies}">
            <tr>
                <td>${item.name}</td>
                <td>${item.starring}</td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>
</code>```

And finally, the project structure

Any ideas on this would be greatly appreciated.

Thanks

答:
<link rel="stylesheet" href="../css/bootstrap.min.css">
and

```<code><link rel="stylesheet" href="../../css/bootstrap.min.css">
</code>```

instead of

```<code><link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css">
</code>```

and java file "property(ServletProperties.FILTER_STATIC_CONTENT_REGEX, "/(images|js|css)/.*");"

i am also faced same issue, now resolved.
it should work

Body:
I'm trying to add Bootstrap to an existing Jersey 2/JSP sample project, using this tutorial as a guide. However, in Chrome console I keep getting 404 errors for Bootstrap's CSS, and the styles won't be loaded.

I tried adding a property in my ResourceConfig:

property(ServletProperties.FILTER_STATIC_CONTENT_REGEX,
            // "/(images|css)/.*");
            "/css/*")

to no avail.

Here's my custom ResourceConfig

package com.xxx.jersey2.config;

import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.mvc.jsp.JspMvcFeature;
import org.glassfish.jersey.servlet.ServletProperties;

public class CustomResourceConfig extends ResourceConfig {
    public CustomResourceConfig() {
        packages("com.xxx");
        register(LoggingFilter.class);
        register(JspMvcFeature.class);
        // it may be also jersey.config.server.mvc.templateBasePath
        // property("jersey.config.server.mvc.templateBasePath", "/WEB-INF/jsp");
        property(JspMvcFeature.TEMPLATE_BASE_PATH, "/WEB-INF/jsp");
        // CSS and JS
        // property(ServletProperties.FILTER_STATIC_CONTENT_REGEX, "/(static|(WEB-INF/css))/");
        property(ServletProperties.FILTER_STATIC_CONTENT_REGEX,
                // "/(images|css)/.*");
                "/css/*");
    }
}

My web.xml

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

  <filter>
    <filter-name>jersey</filter-name>
    <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>

    <init-param>
      <param-name>jersey.config.servlet.filter.forwardOn404</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>com.xxx.jersey2.config.CustomResourceConfig</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>jersey</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

</web-app>

My JSP

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

    <title>Sandbox application</title>
    <link rel="stylesheet" href="../../css/bootstrap.min.css">

Listing Movies

            Name
            Starring

        <c:forEach var="item" items="${it.movies}">

                ${item.name}
                ${item.starring}

        </c:forEach>

And finally, the project structure

Any ideas on this would be greatly appreciated.

Thanks

Body:
<link rel="stylesheet" href="../css/bootstrap.min.css">
and

<link rel="stylesheet" href="../../css/bootstrap.min.css">

instead of

<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css">

and java file "property(ServletProperties.FILTER_STATIC_CONTENT_REGEX, "/(images|js|css)/.*");"

i am also faced same issue, now resolved.
it should work


问:
Remove 2 characters in oracle sql
I have a column that contains 12 digits but user wants only to generate a 10 digits.

I tried the trim, ltrim function but nothing work. Below are the queries I tried.

```<code>ltrim('10', 'column_name')
ltrim('10', column_name)
ltrim(10, column_name)
</code>```

For example I have a column that contains a 12 digit number

```<code>100000000123
100000000456
100000000789
</code>```

and the expected result I want is

```<code>0000000123
0000000456
0000000789
</code>```

答:
To extract the last 10 characters of an input string, regardless of how long the string is (so this will work if some inputs have 10 characters, some 12, and some 15 characters), you could use negative starting position in substr:

```<code>substr(column_name, -10)
</code>```

For example:

```<code>with
  my_table(column_name) as (
    select '0123401234'    from dual union all
    select '0001112223334' from dual union all
    select '12345'         from dual union all
    select '012345012345'  from dual
  )
select column_name, substr(column_name, -10) as substr
from   my_table;

COLUMN_NAME   SUBSTR
------------- ----------
0123401234    0123401234
0001112223334 1112223334
12345
012345012345  2345012345
</code>```

Note in particular the third example. The input has only 5 digits, so obviously you can't get a 10 digit number from it. The result is NULL (undefined).

Note also that if you use something like substr(column_name, 3) you will get just '345' in that case; most likely not the desired result.

Title: Remove 2 characters in oracle sql

Body:
I have a column that contains 12 digits but user wants only to generate a 10 digits.

I tried the trim, ltrim function but nothing work. Below are the queries I tried.

ltrim('10', 'column_name')
ltrim('10', column_name)
ltrim(10, column_name)

For example I have a column that contains a 12 digit number

100000000123
100000000456
100000000789

and the expected result I want is

0000000123
0000000456
0000000789

Body:
To extract the last 10 characters of an input string, regardless of how long the string is (so this will work if some inputs have 10 characters, some 12, and some 15 characters), you could use negative starting position in substr:

substr(column_name, -10)

For example:

with
  my_table(column_name) as (
    select '0123401234'    from dual union all
    select '0001112223334' from dual union all
    select '12345'         from dual union all
    select '012345012345'  from dual
  )
select column_name, substr(column_name, -10) as substr
from   my_table;

COLUMN_NAME   SUBSTR
------------- ----------
0123401234    0123401234
0001112223334 1112223334
12345
012345012345  2345012345

Note in particular the third example. The input has only 5 digits, so obviously you can't get a 10 digit number from it. The result is NULL (undefined).

Note also that if you use something like substr(column_name, 3) you will get just '345' in that case; most likely not the desired result.


问:
C++ Heap Corruption
I haven't done any C++ in a while, but decided to finish a big project I was working on for someone. I am getting the following error message now though...

HEAP CORRUPTION DETECTED: after Normal Block (#1761) at 0x17DEB940.
CRT Detected that the application wrote to memory after end of heap buffer.

I have been stepping through all of the functions I thought might have caused it but I am at a loss. Is there any way using the more advanced debugging features to hunt this down?

答:
It does sound like a classic memory corruption error. The platform would be helpful information. Without seeing your code and it's complexity there are a couple of possibilities:

I'll make a guess that the runtime
library would allow you to add calls to the
heap validation code directly from
your code. I would suggest placing
calls to the heap validation code in
various places in your code so you
can figure out where things go
wrong. You'll find the place where
the heap goes bad and you'll know
that it was ok at the previous call.
Keep narrowing down that window if
you need to and then review the code
where the problem occurs.

If the same steps corrupt exactly the same place in memory,
you should be able to use your
debugger to set a breakpoint (or watchpoint) on the
memory getting changed. Some of
those changes may be intended, but
you should be able to figure out
which one is the culprit.

You might use a combination of the two if your code is particularly complex or the steps needed to reproduce this are long - narrow down a section of code that it problematic and then place a breakpoint on the memory location that gets corrupted.

david

Title: C++ Heap Corruption


问:
How to capture images and attach them to Cucumber Reports (Jenkins) using Selenium Hub, Node and Remote Webdriver?
Currently I'm triggering my automation tests in the cloud using a Ubuntu instance.

The Ubuntu instance has a Jenkins instance running and also Selenium Hub and Node. It seems the screenshot images dont get saved within the builds\3\cucumber-html-reports\embeddings on a ubuntu system however on a windows system this issue does not exist.

I have currently added the below logic to capture and attach images to the Jenkins Cucumber reports however currently the images are not getting attached to the reports:

```<code>@After
public void after(Scenario scenario) {
    if (scenario.isFailed()) {
        try {
            WebDriver augmentedDriver = new Augmenter().augment(getDriver());
            byte[] s = ((TakesScreenshot)augmentedDriver).getScreenshotAs(OutputType.BYTES);
            scenario.embed(s, "image/png");
</code>```

Example Report (Generated in Jenkins), please note the images are getting saved and attached to the reports when running the tests locally.

答:
If this does not work then you may give a thought to below way of attaching screen shot to report on jenkins.

Hooks looks like below -

```<code>@After
    public void afterScenario(Scenario scenario){
        try{
            if(scenario.isFailed()){
                ExtentTestManager.addScreenShotsOnFailure();
    // More code goes here....
</code>```

Method to capture image - please customize path as per your need.

```<code>public static void addScreenShotsOnFailure() {
    i = i + 1;
    File scrFile = ((TakesScreenshot) DriverManager.getDriver()).getScreenshotAs(OutputType.FILE);

    Date d = new Date();
    SimpleDateFormat formatter = new SimpleDateFormat("E dd MMM HH:mm:ss z yyyy");
    String strDate = formatter.format(d);
    screenshotName = strDate.replace(":", "_").replace(" ", "_") + "_"+i+".jpg";

    try {
        FileUtils.copyFile(scrFile, new File(System.getProperty("user.dir") + "/target/extent-report/" + screenshotName));
    } catch (IOException e) {
        e.printStackTrace();
    }
}
</code>```

Body:
Currently I'm triggering my automation tests in the cloud using a Ubuntu instance.

The Ubuntu instance has a Jenkins instance running and also Selenium Hub and Node. It seems the screenshot images dont get saved within the builds\3\cucumber-html-reports\embeddings on a ubuntu system however on a windows system this issue does not exist.

I have currently added the below logic to capture and attach images to the Jenkins Cucumber reports however currently the images are not getting attached to the reports:

@After
public void after(Scenario scenario) {
    if (scenario.isFailed()) {
        try {
            WebDriver augmentedDriver = new Augmenter().augment(getDriver());
            byte[] s = ((TakesScreenshot)augmentedDriver).getScreenshotAs(OutputType.BYTES);
            scenario.embed(s, "image/png");

Example Report (Generated in Jenkins), please note the images are getting saved and attached to the reports when running the tests locally.

Body:
If this does not work then you may give a thought to below way of attaching screen shot to report on jenkins.

Hooks looks like below -

@After
    public void afterScenario(Scenario scenario){
        try{
            if(scenario.isFailed()){
                ExtentTestManager.addScreenShotsOnFailure();
    // More code goes here....

Method to capture image - please customize path as per your need.

public static void addScreenShotsOnFailure() {
    i = i + 1;
    File scrFile = ((TakesScreenshot) DriverManager.getDriver()).getScreenshotAs(OutputType.FILE);

    Date d = new Date();
    SimpleDateFormat formatter = new SimpleDateFormat("E dd MMM HH:mm:ss z yyyy");
    String strDate = formatter.format(d);
    screenshotName = strDate.replace(":", "_").replace(" ", "_") + "_"+i+".jpg";

    try {
        FileUtils.copyFile(scrFile, new File(System.getProperty("user.dir") + "/target/extent-report/" + screenshotName));
    } catch (IOException e) {
        e.printStackTrace();
    }
}


问:
Threads synchronization in C: why do they overlap
I have some code, written in C, I'd like to ask you about:

```<code>#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>

#define COLOR_YELLOW  "\x1b[33m"
#define COLOR_RED    "\x1b[31m"
#define COLOR_RESET   "\x1b[0m"

int tests = 3;
int running_servers;

int servers;
int clients;
int max_clients;

int current_id = 0;
int clients_handled = 0;

void *server(void *arg);
void *client(void *arg);

pthread_mutex_t server_mutex;
pthread_mutex_t client_mutex;

pthread_cond_t order_cond;
pthread_cond_t getting_clients;
pthread_cond_t full;

int main(int argc, char *argv[]) {

     if(argc != 4) { printf("expected 3 arguments"); return 1; }

     // INIT
     servers = atoi(argv[1]);
     running_servers = atoi(argv[1]);
     clients = atoi(argv[2]);
     max_clients = atoi(argv[3]);

     pthread_mutex_init(&server_mutex, NULL);
     pthread_mutex_init(&client_mutex, NULL);

     pthread_cond_init(&order_cond, NULL);
     pthread_cond_init(&getting_clients, NULL);
     pthread_cond_init(&full, NULL);

     pthread_t *server_thread = calloc(servers, sizeof(pthread_t));
     pthread_t *client_thread = calloc(clients, sizeof(pthread_t));

     // CREATING CLIENT THREADS
     int *arg;
     for (int i = 0; i < clients; i++) {
         arg = malloc(sizeof(int));
         *arg = i;
         if (pthread_create(&client_thread[i], NULL, client, (void *) arg))
             perror("pthread_create error for passenger");
     }

     // CREATING SERVER THREADS
     for (int i = 0; i < servers; i++) {
         arg = malloc(sizeof(int));
         *arg = i;
         if (pthread_create(&server_thread[i], NULL, server, (void *) arg))
             perror("pthread_create error for car");
     }

     // JOINING ENDING THREADS
     for (int i = 0; i < servers; i++)
         if (pthread_join(server_thread[i], NULL)) perror("pthread_join error for car");

     for (int i = 0; i < clients; i++)
         if (pthread_join(client_thread[i], NULL)) perror("pthread_join error for passenger");

     return 0;
}

void *server(void *arg) {
     int id = *(int *) arg;

     printf(COLOR_RED "SERVER: %d" COLOR_RESET " start working\n", id);

     while (tests--) {

         // ONLY ONE SERVER CAN WORK - SERVERS ARE RUN IN ORDER
         pthread_mutex_lock(&server_mutex);
         while (id != current_id)
             pthread_cond_wait(&order_cond, &server_mutex);

         printf(COLOR_RED "SERVER: %d" COLOR_RESET " starts\n", id);

         printf(COLOR_RED "SERVER: %d" COLOR_RESET " gets clients \n", id);  // server gets clients
         pthread_cond_broadcast(&getting_clients);

         pthread_cond_wait(&full, &client_mutex);                            // server is waiting for signal (from any client)
         printf(COLOR_RED "SERVER: %d" COLOR_RESET " is full \n", id);       // that he has max number of clients

         printf(COLOR_RED "SERVER: %d" COLOR_RESET " stops \n", id);

         current_id = (current_id + 1) % servers;

         pthread_mutex_unlock(&server_mutex);
         pthread_cond_broadcast(&order_cond);
     }

     running_servers -= 1;
     return NULL;
}

void *client(void *arg) {
     int id = *(int *) arg;

     printf(COLOR_YELLOW "CLIENT: %d" COLOR_RESET " starts\n", id);

     while (running_servers) {
         pthread_mutex_lock(&client_mutex);                      // only one client at the time (should be)

         pthread_cond_wait(&getting_clients, &client_mutex);

         printf(COLOR_YELLOW "CLIENT: %d" COLOR_RESET " has access to server %d\n", id,current_id);

         clients_handled++;

         for (int j = 0; j < 10; j++) {                          // client writes some numbers
             printf("%d:    ", id);
             for (int i = 0; i < 10; i++) {
                 printf("%d  ", 10 * j + i);
             }
             printf("\n");
         }

         if(clients_handled == max_clients) {                    // client sends signal he is the last one server can handle
             printf(COLOR_YELLOW "CLIENT: %d" COLOR_RESET " server %d is full, shifting to next server\n", id, current_id);
             clients_handled = 0;
             pthread_cond_signal(&full);
         }

         pthread_mutex_unlock(&client_mutex);

     }

     return NULL;
}
</code>```

it's not pretty but it's working (sort of).

How it works:
Program gets 3 arguments: number of servers, number of clients, max clients in server. We have servers and clients created as threads. At the moment one client and one server should be active (for that are mutexes server_mutex and client_mutex). Server broadcast info he is active (getting_clients condition), clients are run one next to each other, client writes some numbers, if he is the last one server can handle he signals it (full cond) and server is switchet to next one. I hope you won;t have any problems with running it (as I wrote is works - sort of).

What does not work

it looks like server_mutex does his job, servers are being run one by one, but client_mutex doesn't, and I don't know why sometimes clients overlap - one client starts, while other haven't finished writing numbers.

I have problem with first broadcast of getting_clients, because from unknown reason it is sometimes send while some clients are not yet created. This is especially bad, when I have like 3 servers and 2 clients, and then they may not even start. It's weird for me because client threads are being created first, and I wonder if there is any solution ( except adding sleep() between creating client threads and server threads, but I'd like to avoid that)

for some reason program doesn't end, it just stops in one moment, that may be connected with previous ones, but I haven't found the sollution for that yet,

do you have any ideas what to do, to make all clients be handled equally? I mean I have 3 servers and 100 clients and I wouldn't like to have the situation when few clients write all the time and there is a group which haven't got an access to server yet

I will be grateful for any help :)

答: There is a race. running_servers is accessed concurrently and unprotected.

Body:
I have some code, written in C, I'd like to ask you about:

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>

#define COLOR_YELLOW  "\x1b[33m"
#define COLOR_RED    "\x1b[31m"
#define COLOR_RESET   "\x1b[0m"

int tests = 3;
int running_servers;

int servers;
int clients;
int max_clients;

int current_id = 0;
int clients_handled = 0;

void *server(void *arg);
void *client(void *arg);

pthread_mutex_t server_mutex;
pthread_mutex_t client_mutex;

pthread_cond_t order_cond;
pthread_cond_t getting_clients;
pthread_cond_t full;

int main(int argc, char *argv[]) {

     if(argc != 4) { printf("expected 3 arguments"); return 1; }

     // INIT
     servers = atoi(argv[1]);
     running_servers = atoi(argv[1]);
     clients = atoi(argv[2]);
     max_clients = atoi(argv[3]);

     pthread_mutex_init(&server_mutex, NULL);
     pthread_mutex_init(&client_mutex, NULL);

     pthread_cond_init(&order_cond, NULL);
     pthread_cond_init(&getting_clients, NULL);
     pthread_cond_init(&full, NULL);

     pthread_t *server_thread = calloc(servers, sizeof(pthread_t));
     pthread_t *client_thread = calloc(clients, sizeof(pthread_t));

     // CREATING CLIENT THREADS
     int *arg;
     for (int i = 0; i < clients; i++) {
         arg = malloc(sizeof(int));
         *arg = i;
         if (pthread_create(&client_thread[i], NULL, client, (void *) arg))
             perror("pthread_create error for passenger");
     }

     // CREATING SERVER THREADS
     for (int i = 0; i < servers; i++) {
         arg = malloc(sizeof(int));
         *arg = i;
         if (pthread_create(&server_thread[i], NULL, server, (void *) arg))
             perror("pthread_create error for car");
     }

     // JOINING ENDING THREADS
     for (int i = 0; i < servers; i++)
         if (pthread_join(server_thread[i], NULL)) perror("pthread_join error for car");

     for (int i = 0; i < clients; i++)
         if (pthread_join(client_thread[i], NULL)) perror("pthread_join error for passenger");

     return 0;
}

void *server(void *arg) {
     int id = *(int *) arg;

     printf(COLOR_RED "SERVER: %d" COLOR_RESET " start working\n", id);

     while (tests--) {

         // ONLY ONE SERVER CAN WORK - SERVERS ARE RUN IN ORDER
         pthread_mutex_lock(&server_mutex);
         while (id != current_id)
             pthread_cond_wait(&order_cond, &server_mutex);

         printf(COLOR_RED "SERVER: %d" COLOR_RESET " starts\n", id);

         printf(COLOR_RED "SERVER: %d" COLOR_RESET " gets clients \n", id);  // server gets clients
         pthread_cond_broadcast(&getting_clients);

         pthread_cond_wait(&full, &client_mutex);                            // server is waiting for signal (from any client)
         printf(COLOR_RED "SERVER: %d" COLOR_RESET " is full \n", id);       // that he has max number of clients

         printf(COLOR_RED "SERVER: %d" COLOR_RESET " stops \n", id);

         current_id = (current_id + 1) % servers;

         pthread_mutex_unlock(&server_mutex);
         pthread_cond_broadcast(&order_cond);
     }

     running_servers -= 1;
     return NULL;
}

void *client(void *arg) {
     int id = *(int *) arg;

     printf(COLOR_YELLOW "CLIENT: %d" COLOR_RESET " starts\n", id);

     while (running_servers) {
         pthread_mutex_lock(&client_mutex);                      // only one client at the time (should be)

         pthread_cond_wait(&getting_clients, &client_mutex);

         printf(COLOR_YELLOW "CLIENT: %d" COLOR_RESET " has access to server %d\n", id,current_id);

         clients_handled++;

         for (int j = 0; j < 10; j++) {                          // client writes some numbers
             printf("%d:    ", id);
             for (int i = 0; i < 10; i++) {
                 printf("%d  ", 10 * j + i);
             }
             printf("\n");
         }

         if(clients_handled == max_clients) {                    // client sends signal he is the last one server can handle
             printf(COLOR_YELLOW "CLIENT: %d" COLOR_RESET " server %d is full, shifting to next server\n", id, current_id);
             clients_handled = 0;
             pthread_cond_signal(&full);
         }

         pthread_mutex_unlock(&client_mutex);

     }

     return NULL;
}

it's not pretty but it's working (sort of).

How it works:
Program gets 3 arguments: number of servers, number of clients, max clients in server. We have servers and clients created as threads. At the moment one client and one server should be active (for that are mutexes server_mutex and client_mutex). Server broadcast info he is active (getting_clients condition), clients are run one next to each other, client writes some numbers, if he is the last one server can handle he signals it (full cond) and server is switchet to next one. I hope you won;t have any problems with running it (as I wrote is works - sort of).

What does not work

it looks like server_mutex does his job, servers are being run one by one, but client_mutex doesn't, and I don't know why sometimes clients overlap - one client starts, while other haven't finished writing numbers.

I have problem with first broadcast of getting_clients, because from unknown reason it is sometimes send while some clients are not yet created. This is especially bad, when I have like 3 servers and 2 clients, and then they may not even start. It's weird for me because client threads are being created first, and I wonder if there is any solution ( except adding sleep() between creating client threads and server threads, but I'd like to avoid that)

for some reason program doesn't end, it just stops in one moment, that may be connected with previous ones, but I haven't found the sollution for that yet,

do you have any ideas what to do, to make all clients be handled equally? I mean I have 3 servers and 100 clients and I wouldn't like to have the situation when few clients write all the time and there is a group which haven't got an access to server yet

I will be grateful for any help :)