问:
How to avoid adding field change handling methods and other boilerplates in react form?
I have a react based form with more than 10 fields in it, I have states for those ten form fields (controlled component).

Most of these input fields are of type text only but other types fields will be added later.

Problem is that I need to write 10 change handlers for them to set state correctly and then add method bindings for each of them in constructor.

I am quite new to react and may be not aware about correct
  methodologies and techniques.

Please guide me to how to improve my current code structure and avoid writing boiler plates and repetitive error prone code.

My current Registration component is like below -

```<code>export default class Register extends Component {

    constructor(props){
        super(props);
        this.state = {
            regName              : '',
            regAdd1              : '',
            regAdd2              : '',
            regState             : '',
            regZipCode           : '',
            regCity              : '',
            regPhone             : ''
        };
        // add bindings .... ugh..
        this.changeRegAdd1 = this.changeRegAdd1.bind(this);
        this.changeRegAdd2 = this.changeRegAdd2.bind(this);
        //Similary binding for other handlers...
    }

    // add individual field change handlers ... ugh...
    changeRegName(e) {
        this.setState({regName:e.target.value});
    }

    changeRegAdd1(e) {
        this.setState({regAdd1:e.target.value});
    }

    changeRegAdd2(e) {
        this.setState({regAdd2:e.target.value});
    }

    changeRegState(e) {
        this.setState({regState:e.target.value});
    }

    // Similary for other change handler ....

    handleSubmit(e) {
        e.preventDefault();
        // validate then do other stuff
    }

    render(){

        let registrationComp = (
                <div className="row">
                    <div className="col-md-12">
                        <h3>Registration Form</h3>
                        <fieldset>
                              <div className="form-group">
                                <div className="col-xs-12">
                                    <label htmlFor="regName">Name</label>
                                    <input type="text" placeholder="Name"
                                        onChange={this.changeregName} value = {this.state.regName} className="form-control" required autofocus/>
                                </div>
                              </div>

                              <div className="form-group">
                                <div className="col-xs-12">
                                    <label htmlFor="regAdd1">Address Line1</label>

                                    <input
                                        type        = "text"
                                        placeholder = "Address Line1"
                                        onChange    = {this.changeregAdd1}
                                        value       = {this.state.regAdd1}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />

                                    <input
                                        type        = "text"
                                        placeholder = "Address Line2"
                                        onChange    = {this.changeregAdd2}
                                        value       = {this.state.regAdd2}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />
                                </div>
                              </div>

                              <div className="form-group">
                                <div className="col-xs-6">
                                    <label htmlFor="regState">State</label>
                                    <input
                                        type        = "text"
                                        placeholder = "State"
                                        onChange    = {this.changeregState}
                                        value       = {this.state.regState}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />
                                </div>
                                <div className="col-xs-6">
                                    <label htmlFor="regZipCode">Zip Code</label>
                                    <input
                                        type        = "text"
                                        placeholder = "Zip Code"
                                        onChange    = {this.changeregZipCode}
                                        value       = {this.state.regZipCode}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />
                                </div>
                              </div>

                              <div className="form-group">
                                <div className="col-xs-12">
                                    <label htmlFor="regCity">City</label>
                                    <input
                                        type        = "text"
                                        placeholder = "City"
                                        title       = "City"
                                        onChange    = {this.changeregCity}
                                        value       = {this.state.regCity}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />
                                </div>
                              </div>
                              {/* other form fields */}
                          </fieldset>
                      </div>
                    </div>
            );

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

答:
There can be other lots of ways to do it which I may not be aware.

But I prefer to do change handling in a common method for certain type of common fields such as  <input type of text />

This is a sample input field -

```<code>  <input
      onChange    = {this.onChange}
      value       = {this.state.firstName}
      type        = "text"
      name        = {"firstName"}
  />
</code>```

I keep both state's field name and input's "name" attribute same.
After that I write a common change handler for all such fields.

Need to write just one line in change handler.

```<code>onChange(e) {
    this.setState({[e.target.name]: e.target.value});
}
</code>```

I am using es6's dynamic property setting from string as property name

```<code>{ ["propName] : propValue }.
</code>```

To avoid writing manual binding for methods in react component you can follow below two approaches -

Use es6 arrow functions

A hack ( I don't know whether this approach is fast or slow but It works :) )

create a method like this in your component.

```<code>_bind(...methods) {
  methods.forEach( (method) => this[method] = this[method].bind(this) );
 }
</code>```

use _bind to bind your methods.

```<code>constructor(props){
    super(props);
    this.state = {
        regName              : '',
        regAdd1              : '',
        regAdd2              : '',
        regState             : '',
        regZipCode           : '',
        regCity              : '',
        regPhone             : ''
    };
    // add bindings .... ugh..
    //this.changeRegAdd1 = this.changeRegAdd1.bind(this);
    //this.changeRegAdd2 = this.changeRegAdd2.bind(this);
    //Similary binding for other handlers...

    this._bind(
        'changeRegName',
        'changeReg1'    , 'changeRegAdd2'
        // and so on.
    );

}
</code>```

EDIT :

Adding validation -

Write a method which can iterate over state keys and check if state is empty.

If any of the input field is empty collect the detail about that input and mark that required.

set a state to indicate that form has errors. Specific error details can be found in state's error object.

```<code>validateInput() {
    let errors = {};

    Object.keys(this.state)
    .forEach((stateKey) => {
    isEmpty(this.state[stateKey]) ? (errors[stateKey] = `*required` ) : null;
});

    return {
       errors,
       isValid : isEmptyObj(errors)
   };
}

isFormValid() {
   const { errors, isValid } = this.validateInput();

   if (!isValid) {
      this.setState({ errors});
   }

   return isValid;
 }

 onSubmit(e) {
     e.preventDefault();

     this.setState({errors : {}});

     if (this.isFormValid()) {
        // Perform form submission
     }
  }
</code>```

I have used to utility method calld isEmpty, isEmptyObj. They just check if object is null or undefined or field is empty.

I hope this helps.

Body:
I have a react based form with more than 10 fields in it, I have states for those ten form fields (controlled component).

Most of these input fields are of type text only but other types fields will be added later.

Problem is that I need to write 10 change handlers for them to set state correctly and then add method bindings for each of them in constructor.

I am quite new to react and may be not aware about correct
  methodologies and techniques.

Please guide me to how to improve my current code structure and avoid writing boiler plates and repetitive error prone code.

My current Registration component is like below -

export default class Register extends Component {

    constructor(props){
        super(props);
        this.state = {
            regName              : '',
            regAdd1              : '',
            regAdd2              : '',
            regState             : '',
            regZipCode           : '',
            regCity              : '',
            regPhone             : ''
        };
        // add bindings .... ugh..
        this.changeRegAdd1 = this.changeRegAdd1.bind(this);
        this.changeRegAdd2 = this.changeRegAdd2.bind(this);
        //Similary binding for other handlers...
    }

    // add individual field change handlers ... ugh...
    changeRegName(e) {
        this.setState({regName:e.target.value});
    }

    changeRegAdd1(e) {
        this.setState({regAdd1:e.target.value});
    }

    changeRegAdd2(e) {
        this.setState({regAdd2:e.target.value});
    }

    changeRegState(e) {
        this.setState({regState:e.target.value});
    }

    // Similary for other change handler ....

    handleSubmit(e) {
        e.preventDefault();
        // validate then do other stuff
    }

    render(){

        let registrationComp = (

Registration Form

                        <fieldset>

                                    Name
                                    <input type="text" placeholder="Name"
                                        onChange={this.changeregName} value = {this.state.regName} className="form-control" required autofocus/>

                                    Address Line1

                                    <input
                                        type        = "text"
                                        placeholder = "Address Line1"
                                        onChange    = {this.changeregAdd1}
                                        value       = {this.state.regAdd1}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />

                                    <input
                                        type        = "text"
                                        placeholder = "Address Line2"
                                        onChange    = {this.changeregAdd2}
                                        value       = {this.state.regAdd2}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />

                                    State
                                    <input
                                        type        = "text"
                                        placeholder = "State"
                                        onChange    = {this.changeregState}
                                        value       = {this.state.regState}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />

                                    Zip Code
                                    <input
                                        type        = "text"
                                        placeholder = "Zip Code"
                                        onChange    = {this.changeregZipCode}
                                        value       = {this.state.regZipCode}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />

                                    City
                                    <input
                                        type        = "text"
                                        placeholder = "City"
                                        title       = "City"
                                        onChange    = {this.changeregCity}
                                        value       = {this.state.regCity}
                                        className   = "form-control"
                                        required
                                        autofocus
                                    />

                              {/* other form fields */}
                          </fieldset>

            );

            return  registrationComp;
    }
}

Body:
There can be other lots of ways to do it which I may not be aware.

But I prefer to do change handling in a common method for certain type of common fields such as  <input type of text />

This is a sample input field -

  <input
      onChange    = {this.onChange}
      value       = {this.state.firstName}
      type        = "text"
      name        = {"firstName"}
  />

I keep both state's field name and input's "name" attribute same.
After that I write a common change handler for all such fields.

Need to write just one line in change handler.

onChange(e) {
    this.setState({[e.target.name]: e.target.value});
}

I am using es6's dynamic property setting from string as property name

{ ["propName] : propValue }.

To avoid writing manual binding for methods in react component you can follow below two approaches -

Use es6 arrow functions

A hack ( I don't know whether this approach is fast or slow but It works :) )

create a method like this in your component.

_bind(...methods) {
  methods.forEach( (method) => this[method] = this[method].bind(this) );
 }

use _bind to bind your methods.

constructor(props){
    super(props);
    this.state = {
        regName              : '',
        regAdd1              : '',
        regAdd2              : '',
        regState             : '',
        regZipCode           : '',
        regCity              : '',
        regPhone             : ''
    };
    // add bindings .... ugh..
    //this.changeRegAdd1 = this.changeRegAdd1.bind(this);
    //this.changeRegAdd2 = this.changeRegAdd2.bind(this);
    //Similary binding for other handlers...

    this._bind(
        'changeRegName',
        'changeReg1'    , 'changeRegAdd2'
        // and so on.
    );

}

EDIT :

Adding validation -

Write a method which can iterate over state keys and check if state is empty.

If any of the input field is empty collect the detail about that input and mark that required.

set a state to indicate that form has errors. Specific error details can be found in state's error object.

validateInput() {
    let errors = {};

    Object.keys(this.state)
    .forEach((stateKey) => {
    isEmpty(this.state[stateKey]) ? (errors[stateKey] = `*required` ) : null;
});

    return {
       errors,
       isValid : isEmptyObj(errors)
   };
}

isFormValid() {
   const { errors, isValid } = this.validateInput();

   if (!isValid) {
      this.setState({ errors});
   }

   return isValid;
 }

 onSubmit(e) {
     e.preventDefault();

     this.setState({errors : {}});

     if (this.isFormValid()) {
        // Perform form submission
     }
  }

I have used to utility method calld isEmpty, isEmptyObj. They just check if object is null or undefined or field is empty.

I hope this helps.


来源: stackexchange

问:
Convert seconds value to hours minutes seconds?
I've been trying to convert a value of seconds (in a BigDecimal variable) to a string in an editText like "1 hour 22 minutes 33 seconds" or something of the kind.

I've tried this:

```<code>String sequenceCaptureTime = "";
BigDecimal roundThreeCalc = new BigDecimal("0");
BigDecimal hours = new BigDecimal("0");
BigDecimal myremainder = new BigDecimal("0");
BigDecimal minutes = new BigDecimal("0");
BigDecimal seconds = new BigDecimal("0");
BigDecimal var3600 = new BigDecimal("3600");
BigDecimal var60 = new BigDecimal("60");
</code>```

(I have a roundThreeCalc which is the value in seconds so I try to convert it here.)

```<code>hours = (roundThreeCalc.divide(var3600));
myremainder = (roundThreeCalc.remainder(var3600));
minutes = (myremainder.divide(var60));
seconds = (myremainder.remainder(var60));
sequenceCaptureTime =  hours.toString() + minutes.toString() + seconds.toString();
</code>```

Then I set the editText to sequnceCaptureTime String.
But that didn't work. It force closed the app every time. I am totally out of my depth here, any help is greatly appreciated.

答:
I use this in python to convert a float representing seconds to hours, minutes, seconds, and microseconds. It's reasonably elegant and is handy for converting to a datetime type via strptime to convert.  It could also be easily extended to longer intervals (weeks, months, etc.) if needed.</p>

```<code>    def sectohmsus(seconds):
        x = seconds
        hmsus = []
        for i in [3600, 60, 1]:  # seconds in a hour, minute, and second
            hmsus.append(int(x / i))
            x %= i
        hmsus.append(int(round(x * 1000000)))  # microseconds
        return hmsus  # hours, minutes, seconds, microsecond
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I've been trying to convert a value of seconds (in a BigDecimal variable) to a string in an editText like "1 hour 22 minutes 33 seconds" or something of the kind.

I've tried this:

String sequenceCaptureTime = "";
BigDecimal roundThreeCalc = new BigDecimal("0");
BigDecimal hours = new BigDecimal("0");
BigDecimal myremainder = new BigDecimal("0");
BigDecimal minutes = new BigDecimal("0");
BigDecimal seconds = new BigDecimal("0");
BigDecimal var3600 = new BigDecimal("3600");
BigDecimal var60 = new BigDecimal("60");

(I have a roundThreeCalc which is the value in seconds so I try to convert it here.)

hours = (roundThreeCalc.divide(var3600));
myremainder = (roundThreeCalc.remainder(var3600));
minutes = (myremainder.divide(var60));
seconds = (myremainder.remainder(var60));
sequenceCaptureTime =  hours.toString() + minutes.toString() + seconds.toString();

Then I set the editText to sequnceCaptureTime String.
But that didn't work. It force closed the app every time. I am totally out of my depth here, any help is greatly appreciated.

Body:
I use this in python to convert a float representing seconds to hours, minutes, seconds, and microseconds. It's reasonably elegant and is handy for converting to a datetime type via strptime to convert.  It could also be easily extended to longer intervals (weeks, months, etc.) if needed.

    def sectohmsus(seconds):
        x = seconds
        hmsus = []
        for i in [3600, 60, 1]:  # seconds in a hour, minute, and second
            hmsus.append(int(x / i))
            x %= i
        hmsus.append(int(round(x * 1000000)))  # microseconds
        return hmsus  # hours, minutes, seconds, microsecond

ContentLicense: CC BY-SA 3.0


问:
Java - access to variable within inner class or assign a value to final variable
I need to create several buttons and upload files. So I want to create a function to set these buttons. However, I'm getting a compilation error inside of my setNewButton.

My code is shown as below:

public class Solution extends JFrame {
    private static final String FILE_NAME_1 = "my file1";
    private File file1;
    private void setNewButton(Container contentPane, final String fileName, String format, File file) {
        contentPane.add(Box.createVerticalStrut(5));
        final Label label = new Label("Select " + fileName + " in ." + format +" format");
        contentPane.add(label);
        contentPane.add(Box.createVerticalStrut(10));
        Button selection = new Button("Select " + fileName);
        contentPane.add(selection);
        selection.addActionListener(new FileSelectionListener("Only " + format + " is allowed", format) {
            @Override
            protected void setSelection(File selectedFile) {
                file = selectedFile;  // compilation error here
                label.setText("Selected" + fileName + selectedFile.getAbsolutePath());
            }
        });
    }

    public uploadFiles() {
        Container contentPane = this.getContentPane();
        setNewButton(contentPane, FILE_NAME_1, "xls", file1);
    }
}
```

<p>The error is: <code>Variable file is accessed from within inner class, needs to be declared final</code></p>

<p>I have checked some similar questions in stackoverflow. I know <code>file</code> has to be final like <code>label</code> and <code>fileName</code> here.</p>

<p>However <code>file</code> here could be <code>final</code> since I would like to assign <code>selectedFile</code> to it.</p>

<p>I would like to know if there is any walkaround for this problem.</p>

<p>Any help would be appreciated. :)</p>

<p>Thanks to @M. Prokhorov and @Chang Liu.
According to  JLS 8.1.3. Inner Classes and Enclosing Instances</p>

<blockquote>
  <p>Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final, or a compile-time error occurs where the use is attempted.</p>
</blockquote>

<p>So when I tried to send a parameter <code>file</code> inside <code>FileSlectionListener</code>, there will be a compile error. However, the member <code>file1</code> inside Solution is not local variable, so if I delete the <code>file</code> from my method, there will be no error. So @talex 's anwser is right in this case.</p>

<p>However since my problem is to find a method to pass a <code>File</code> to inner class and assign the variable with <code>selectedFile</code>, I couldn't find a way for it. My workaround is based on @Chang Liu's answer.</p>

<p>My revised code is as below:</p>

<pre class="lang-java prettyprint-override"><code>public class Solution extends JFrame {
    private static final String FILE_NAME_1 = "my file1";
    private File file1;
    private void setNewButton(Container contentPane, final String fileName, String format) {
        contentPane.add(Box.createVerticalStrut(5));
        final Label label = new Label("Select " + fileName + " in ." + format +" format");
        contentPane.add(label);
        contentPane.add(Box.createVerticalStrut(10));
        Button selection = new Button("Select " + fileName);
        contentPane.add(selection);
        selection.addActionListener(new FileSelectionListener("Only " + format + " is allowed", format) {
            @Override
            protected void setSelection(File selectedFile) {
                setFile(selectedFile, fileName);  // no compilation error here
                label.setText("Selected" + fileName + selectedFile.getAbsolutePath());
            }
        });
    }

    public uploadFiles() {
        Container contentPane = this.getContentPane();
        setNewButton(contentPane, FILE_NAME_1, "xls", file1);
    }

    private void setFile(File file, String fileName) {
        switch (fileName) {
            case FILE_NAME_1:
                sollFile = file;
                break;
            default:
                throw new AssertionError("Unknown File");
        }
    }
}
</code>```

Still, welcome to give me any advise if you have a better answer. :)

答:
Just extract your action listener to be named inner class of Solution and you will be able to assign Solution.this.file from the inner class :</p>

```<code>public class Solution extends JFrame {
   private class MyListener extends FileSelectionListener{
@Override
            protected void setSelection(File selectedFile) {
                Solution.this.file = selectedFile;  // NO compilation error here
            }
}
    private static final String FILE_NAME_1 = "Selected SOLL:";
    private File file;
    private void setNewButton(Container contentPane, final String fileName, String format, File file) {
        contentPane.add(Box.createVerticalStrut(5));
        final Label label = new Label("Select " + fileName + " in ." + format +" format");
        contentPane.add(label);
        contentPane.add(Box.createVerticalStrut(10));
        Button selection = new Button("Select " + fileName);
        contentPane.add(selection);
        selection.addActionListener(new MyListener() );
    }

    public uploadFiles() {
        Container contentPane = this.getContentPane();
        setNewButton(contentPane, FILE_NAME_1, "xls", file1);
    }
}
</code>```

Body:
I need to create several buttons and upload files. So I want to create a function to set these buttons. However, I'm getting a compilation error inside of my setNewButton.

My code is shown as below:

public class Solution extends JFrame {
    private static final String FILE_NAME_1 = "my file1";
    private File file1;
    private void setNewButton(Container contentPane, final String fileName, String format, File file) {
        contentPane.add(Box.createVerticalStrut(5));
        final Label label = new Label("Select " + fileName + " in ." + format +" format");
        contentPane.add(label);
        contentPane.add(Box.createVerticalStrut(10));
        Button selection = new Button("Select " + fileName);
        contentPane.add(selection);
        selection.addActionListener(new FileSelectionListener("Only " + format + " is allowed", format) {
            @Override
            protected void setSelection(File selectedFile) {
                file = selectedFile;  // compilation error here
                label.setText("Selected" + fileName + selectedFile.getAbsolutePath());
            }
        });
    }

    public uploadFiles() {
        Container contentPane = this.getContentPane();
        setNewButton(contentPane, FILE_NAME_1, "xls", file1);
    }
}

The error is: Variable file is accessed from within inner class, needs to be declared final

I have checked some similar questions in stackoverflow. I know file has to be final like label and fileName here.

However file here could be final since I would like to assign selectedFile to it.

I would like to know if there is any walkaround for this problem.

Any help would be appreciated. :)

Thanks to @M. Prokhorov and @Chang Liu.
According to  JLS 8.1.3. Inner Classes and Enclosing Instances

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final, or a compile-time error occurs where the use is attempted.

So when I tried to send a parameter file inside FileSlectionListener, there will be a compile error. However, the member file1 inside Solution is not local variable, so if I delete the file from my method, there will be no error. So @talex 's anwser is right in this case.

However since my problem is to find a method to pass a File to inner class and assign the variable with selectedFile, I couldn't find a way for it. My workaround is based on @Chang Liu's answer.

My revised code is as below:

public class Solution extends JFrame {
    private static final String FILE_NAME_1 = "my file1";
    private File file1;
    private void setNewButton(Container contentPane, final String fileName, String format) {
        contentPane.add(Box.createVerticalStrut(5));
        final Label label = new Label("Select " + fileName + " in ." + format +" format");
        contentPane.add(label);
        contentPane.add(Box.createVerticalStrut(10));
        Button selection = new Button("Select " + fileName);
        contentPane.add(selection);
        selection.addActionListener(new FileSelectionListener("Only " + format + " is allowed", format) {
            @Override
            protected void setSelection(File selectedFile) {
                setFile(selectedFile, fileName);  // no compilation error here
                label.setText("Selected" + fileName + selectedFile.getAbsolutePath());
            }
        });
    }

    public uploadFiles() {
        Container contentPane = this.getContentPane();
        setNewButton(contentPane, FILE_NAME_1, "xls", file1);
    }

    private void setFile(File file, String fileName) {
        switch (fileName) {
            case FILE_NAME_1:
                sollFile = file;
                break;
            default:
                throw new AssertionError("Unknown File");
        }
    }
}

Still, welcome to give me any advise if you have a better answer. :)

Body:
Just extract your action listener to be named inner class of Solution and you will be able to assign Solution.this.file from the inner class :

public class Solution extends JFrame {
   private class MyListener extends FileSelectionListener{
@Override
            protected void setSelection(File selectedFile) {
                Solution.this.file = selectedFile;  // NO compilation error here
            }
}
    private static final String FILE_NAME_1 = "Selected SOLL:";
    private File file;
    private void setNewButton(Container contentPane, final String fileName, String format, File file) {
        contentPane.add(Box.createVerticalStrut(5));
        final Label label = new Label("Select " + fileName + " in ." + format +" format");
        contentPane.add(label);
        contentPane.add(Box.createVerticalStrut(10));
        Button selection = new Button("Select " + fileName);
        contentPane.add(selection);
        selection.addActionListener(new MyListener() );
    }

    public uploadFiles() {
        Container contentPane = this.getContentPane();
        setNewButton(contentPane, FILE_NAME_1, "xls", file1);
    }
}


问:
Are infinite lists useful for any real world applications?
I've been using haskell for quite a while now, and I've read most of Real World Haskell and Learn You a Haskell. What I want to know is whether there is a point to a language using lazy evaluation, in particular the "advantage" of having infinite lists, is there a task which infinite lists make very easy, or even a task that is only possible with infinite lists?</p>

答:
Here's an utterly trivial but actually day-to-day useful example of where infinite lists specifically come in handy: When you have a list of items that you want to use to initialize some key-value-style data structure, starting with consecutive keys. So, say you have a list of strings and you want to put them into an IntMap counting from 0. Without lazy infinite lists, you'd do something like walk down the input list, keeping a running "next index" counter and building up the IntMap as you go.

With infinite lazy lists, the list itself takes the role of the running counter; just use zip [0..] with your list of items to assign the indices, then IntMap.fromList to construct the final result.

Sure, it's essentially the same thing in both cases. But having lazy infinite lists lets you express the concept much more directly without having to worry about details like the length of the input list or keeping track of an extra counter.

ContentLicense: CC BY-SA 2.5


问:
download file to custom directory
I am using the DownloadManager to download a file to my Android device. I can choose to download to the DCIM, Downloads, Picutures folder, etc using:

```<code>downloadRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "file.jpg");
</code>```

This works. But I can only choose a limit set of folders to download to. I want to download to the root of my sdcard using /sdcard/

I tried:

```<code>downloadRequest.setDestinationUri(Uri.fromFile(new File("/sdcard/file.jpg")));
</code>```

But this renders the following exception:

IllegalStateException: android invalid combination of destination: 4, path: /sdcard/file.jpg

How can I do this? I have all the required permissions set.

答:
As per the official documentation, you should only use either of the following variants, using one of the available Environment.DIRECTORY_* constants:

```<code>myRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "my_sub_folder/my_file.txt");
</code>```

where the directory type (i.e. the first parameter) may not be null, or

```<code>myRequest.setDestinationInExternalFilesDir(myContext, null, "my_sub_folder/my_file.txt");
// or
// myRequest.setDestinationInExternalFilesDir(myContext, Environment.DIRECTORY_PICTURES, "my_sub_folder/my_picture.jpg");
</code>```

where the directory type (i.e. the second parameter) may be null.

In any case, specifying a (sub)folder in the last parameter is optional.

Title: download file to custom directory

Body:
I am using the DownloadManager to download a file to my Android device. I can choose to download to the DCIM, Downloads, Picutures folder, etc using:

downloadRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "file.jpg");

This works. But I can only choose a limit set of folders to download to. I want to download to the root of my sdcard using /sdcard/

I tried:

downloadRequest.setDestinationUri(Uri.fromFile(new File("/sdcard/file.jpg")));

But this renders the following exception:

IllegalStateException: android invalid combination of destination: 4, path: /sdcard/file.jpg

How can I do this? I have all the required permissions set.

Body:
As per the official documentation, you should only use either of the following variants, using one of the available Environment.DIRECTORY_* constants:

myRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "my_sub_folder/my_file.txt");

where the directory type (i.e. the first parameter) may not be null, or

myRequest.setDestinationInExternalFilesDir(myContext, null, "my_sub_folder/my_file.txt");
// or
// myRequest.setDestinationInExternalFilesDir(myContext, Environment.DIRECTORY_PICTURES, "my_sub_folder/my_picture.jpg");

where the directory type (i.e. the second parameter) may be null.

In any case, specifying a (sub)folder in the last parameter is optional.


问:
Failed to login, Forbidden, using hawtio offline war file with ActiveMQ
I'm trying to use hawtio 1.5.2 offline war file as a webapp within ActiveMQ 5.14.5.  I have added what I believe are the required entries to ACTIVEMQ_OPTS in $ACTIVEMQ_HOME/bin/env

-Dhawtio.role=admins -Dhawtio.rolePrincipalClasses=org.apache.activemq.jaas.GroupPrincipal -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config

and when I go to http://localhost:8161/hawtio I get the login screen, but after using admin/admin and trying to login I get the error Failed to login, forbidden.

I am however able to use the executable JAR for hawtio and connect to my server, so I believe I must be missing something in the ActiveMQ configuration to allow this to work.

I have tried adding log4j.logger.io.hawt=DEBUG to my ActiveMQ's log4j.properties file but I don't seem to get any feedback in the logs from hawtio.

Can anyone help?  Thanks

答:
I found my problem.  I didn't have this entry in ACTIVEMQ_OPTS in $ACTIVEMQ_HOME/bin/env

```<code>-Dhawtio.realm=activemq
</code>```

Now with my entry reading

```<code>ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY \
    -Djava.util.logging.config.file=logging.properties \
    -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config \
    -Dhawtio.realm=activemq \
    -Dhawtio.role=admins \
    -Dhawtio.rolePrincipalClasses=org.apache.activemq.jaas.GroupPrincipal"
</code>```

I'm able to login.

Body:
I found my problem.  I didn't have this entry in ACTIVEMQ_OPTS in $ACTIVEMQ_HOME/bin/env

-Dhawtio.realm=activemq

Now with my entry reading

ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY \
    -Djava.util.logging.config.file=logging.properties \
    -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config \
    -Dhawtio.realm=activemq \
    -Dhawtio.role=admins \
    -Dhawtio.rolePrincipalClasses=org.apache.activemq.jaas.GroupPrincipal"

I'm able to login.


问:
If...Else Statement always diverts to "else".
I am trying to run a "presence check" on a radio group, to determine what happens if 1 of 2 radiobuttons are selected in the group (if statement), if the other of the 2 radiobuttons is selected instead (else if statement) or if neither are selected (else statement). The code for this is as follows:

```<code>if (rdbAM.isSelected()) {
        strTime = rdbAM.getText().toString();
    } else if(rdbPM.isSelected()){
        strTime = rdbPM.getText().toString();
    } else {
        AlertDialog.Builder WrongDateFormat = new AlertDialog.Builder(this);
        WrongDateFormat.setMessage("Please Select AM or PM");
        WrongDateFormat.setNeutralButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
            }
        });
        AlertDialog alertWrongDateFormat = WrongDateFormat.create();
        alertWrongDateFormat.show();
        return;
    }
</code>```

So basically, what this should do is either, set the variable called "strTime" to whatever the text of the selected radiobutton in the radiogroup is, or display an error message if neither are selected. It is instead always displaying this error message, regardless of whether either radiobutton is selected or not:

(As you can see above, the "AM" radiobutton is selected, but error is still being displayed).

Any suggestions as to why this may be would be appreciated. Please note that I am relatively new to Android development, so if it is clearly something obvious then I apologise, but I have been trying to get my head round this for several days now! If you would like to see any further code, please let me know and I'll be happy to provide it, but am trying to keep it as private as possible, so didn't want to post everything in the initial post if not necessary. Thanks in advance.

答:
A RadioButton is a two-states button that can be either checked or unchecked. For this compound button, you should use method isChecked() to know its current state.

See documentation.

Update your code as below:

```<code>if (rdbAM.isChecked()) {
        strTime = rdbAM.getText().toString();
    } else if(rdbPM.isChecked()){
        strTime = rdbPM.getText().toString();
    } else {
        AlertDialog.Builder WrongDateFormat = new AlertDialog.Builder(this);
        WrongDateFormat.setMessage("Please Select AM or PM");
        WrongDateFormat.setNeutralButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
            }
        });
        AlertDialog alertWrongDateFormat = WrongDateFormat.create();
        alertWrongDateFormat.show();
        return;
    }
</code>```

Body:
I am trying to run a "presence check" on a radio group, to determine what happens if 1 of 2 radiobuttons are selected in the group (if statement), if the other of the 2 radiobuttons is selected instead (else if statement) or if neither are selected (else statement). The code for this is as follows:

if (rdbAM.isSelected()) {
        strTime = rdbAM.getText().toString();
    } else if(rdbPM.isSelected()){
        strTime = rdbPM.getText().toString();
    } else {
        AlertDialog.Builder WrongDateFormat = new AlertDialog.Builder(this);
        WrongDateFormat.setMessage("Please Select AM or PM");
        WrongDateFormat.setNeutralButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
            }
        });
        AlertDialog alertWrongDateFormat = WrongDateFormat.create();
        alertWrongDateFormat.show();
        return;
    }

So basically, what this should do is either, set the variable called "strTime" to whatever the text of the selected radiobutton in the radiogroup is, or display an error message if neither are selected. It is instead always displaying this error message, regardless of whether either radiobutton is selected or not:

(As you can see above, the "AM" radiobutton is selected, but error is still being displayed).

Any suggestions as to why this may be would be appreciated. Please note that I am relatively new to Android development, so if it is clearly something obvious then I apologise, but I have been trying to get my head round this for several days now! If you would like to see any further code, please let me know and I'll be happy to provide it, but am trying to keep it as private as possible, so didn't want to post everything in the initial post if not necessary. Thanks in advance.

Body:
A RadioButton is a two-states button that can be either checked or unchecked. For this compound button, you should use method isChecked() to know its current state.

See documentation.

Update your code as below:

if (rdbAM.isChecked()) {
        strTime = rdbAM.getText().toString();
    } else if(rdbPM.isChecked()){
        strTime = rdbPM.getText().toString();
    } else {
        AlertDialog.Builder WrongDateFormat = new AlertDialog.Builder(this);
        WrongDateFormat.setMessage("Please Select AM or PM");
        WrongDateFormat.setNeutralButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
            }
        });
        AlertDialog alertWrongDateFormat = WrongDateFormat.create();
        alertWrongDateFormat.show();
        return;
    }


问:
Nginx serve images from multiple static directories under one alias
I am making transition from apache to nginx, and i can not get the alias to serve images. Reading nginx documentation, diving in google and what not have not yielded any acceptable results for me ;(

The images is located C:/xampp/htdocs/content/XYZ/thumbn/image.jpg

the XYZ part is dynamic and changes.

Nginx is set up to serve content from  root C:/nginx/public_html/domain.dev/

In the apache i had simply made Alias /CDN "C:\xampp\htdocs\content"

So that way when ever i request www.domain.dev/CDN/XYZ/thumbn/image.jpg i would get the image from the alias directory.

So im trying to replicate the same in nginx

```<code>location /CDN {
alias C:/xampp/htdocs/content;
autoindex on; # just there to see if it works.
}
</code>```

Unfortunately when i access the image www.domain.dev/CDN/XYZ/thumbn/image.jpg i get 404. In the Nginx logs i see following record :

```<code>2017/07/04 16:43:32 [error] 10532#6488: *4 CreateFile() "C:/nginx/public_html/domain.dev/CDN/XYZ/thumbn/two.jpg" failed (3: The system cannot find the path specified), client: 127.0.0.1, server: www.domain.dev, request: "GET /CDN/XYZ/thumbn/two.jpg HTTP/1.1", host: "www.domain.dev"
</code>```

it is how ever listing the directory contents.

Now if i change the location block to this

```<code>    location ^~ /CDN/ {
        alias C:/xampp/htdocs/content/;
    }
</code>```

I get the same error in log, only way i managed to get it working (but not in the way i need) was when i use this location block

```<code>    location ^~ /CDN/ {
        alias C:/xampp/htdocs/content/XYZ/thumbn/;
    }
</code>```

Then it is showing the image, but the url for the image is different and not valid for my project.

Now the question: how do i serve only images from multiple static directories under same alias?
the images are located in following structure

```<code>C:/xampp/htdocs/content/one/thumbn/image.jpg
C:/xampp/htdocs/content/two/thumbn/cats.jpg
C:/xampp/htdocs/content/three/thumbn/dogs.jpg
C:/xampp/htdocs/content/another_random_direcotry/thumbn/random.jpg
</code>```

And they should be accessed by URL as follows

```<code>www.domain.dev/CDN/one/thumbn/image.jpg
www.domain.dev/CDN/two/thumbn/cats.jpg
www.domain.dev/CDN/three/thumbn/dogs.jpg
www.domain.dev/CDN/another_random_direcotry/thumbn/random.jpg
</code>```

Is this even possible with Nginx? so how do i achieve this? Is regex required in this occasion?

full config file here

答:
try this</p>

```<code>location /CDN/ {
        alias C:/xampp/htdocs/content/;
}
</code>```

Body:
I am making transition from apache to nginx, and i can not get the alias to serve images. Reading nginx documentation, diving in google and what not have not yielded any acceptable results for me ;(

The images is located C:/xampp/htdocs/content/XYZ/thumbn/image.jpg

the XYZ part is dynamic and changes.

Nginx is set up to serve content from  root C:/nginx/public_html/domain.dev/

In the apache i had simply made Alias /CDN "C:\xampp\htdocs\content"

So that way when ever i request www.domain.dev/CDN/XYZ/thumbn/image.jpg i would get the image from the alias directory.

So im trying to replicate the same in nginx

location /CDN {
alias C:/xampp/htdocs/content;
autoindex on; # just there to see if it works.
}

Unfortunately when i access the image www.domain.dev/CDN/XYZ/thumbn/image.jpg i get 404. In the Nginx logs i see following record :

2017/07/04 16:43:32 [error] 10532#6488: *4 CreateFile() "C:/nginx/public_html/domain.dev/CDN/XYZ/thumbn/two.jpg" failed (3: The system cannot find the path specified), client: 127.0.0.1, server: www.domain.dev, request: "GET /CDN/XYZ/thumbn/two.jpg HTTP/1.1", host: "www.domain.dev"

it is how ever listing the directory contents.

Now if i change the location block to this

    location ^~ /CDN/ {
        alias C:/xampp/htdocs/content/;
    }

I get the same error in log, only way i managed to get it working (but not in the way i need) was when i use this location block

    location ^~ /CDN/ {
        alias C:/xampp/htdocs/content/XYZ/thumbn/;
    }

Then it is showing the image, but the url for the image is different and not valid for my project.

Now the question: how do i serve only images from multiple static directories under same alias?
the images are located in following structure

C:/xampp/htdocs/content/one/thumbn/image.jpg
C:/xampp/htdocs/content/two/thumbn/cats.jpg
C:/xampp/htdocs/content/three/thumbn/dogs.jpg
C:/xampp/htdocs/content/another_random_direcotry/thumbn/random.jpg

And they should be accessed by URL as follows

www.domain.dev/CDN/one/thumbn/image.jpg
www.domain.dev/CDN/two/thumbn/cats.jpg
www.domain.dev/CDN/three/thumbn/dogs.jpg
www.domain.dev/CDN/another_random_direcotry/thumbn/random.jpg

Is this even possible with Nginx? so how do i achieve this? Is regex required in this occasion?

full config file here

Body:
try this

location /CDN/ {
        alias C:/xampp/htdocs/content/;
}


问:
Composer install using Homestead gives error "Your requirements could not be resolved to an installable set of packages"
I am trying to install my composer packages using the following command:

```<code>composer install --no-dev --no-scripts
</code>```

The  composer.json file looks like this (it's very similar to the standard Laravel composer file):

```<code>{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.2.*",
        "doctrine/dbal": "^2.5",
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~4.0",
        "symfony/css-selector": "2.8.*|3.0.*",
        "symfony/dom-crawler": "2.8.*|3.0.*",
        "laravel/homestead": "^5.2",
        "barryvdh/laravel-ide-helper": "^2.3"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "classmap": [
            "tests/TestCase.php"
        ]
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist"
    }
}
</code>```

However when I try to install it on my production machine (which runs PHP on version v5.5.9 I get the following error:

Your requirements could not be resolved to an installable set of packages.

```<code>  Problem 1
    - laravel/homestead v5.4.0 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.3.2 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.3.1 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.3.0 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.2.4 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.2.1 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.2.0 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead 5.2.3 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead 5.2.2 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - Installation request for laravel/homestead ^5.2 -> satisfiable by laravel/homestead[5.2.2, 5.2.3, v5.2.0, v5.2.1, v5.2.4, v5.3.0, v5.3.1, v5.3.2, v5.4.0].
</code>```

So my questions is as follows:

Why is homestead even being installed when I said --no-dev and homestead is a dev package?

If I did want to install Homestead on my production machine, how can I solve the above problem?

答:
--no-dev should not install the dev dependencies. Check your production build scripts (or whatever you are using to run this on production), that --no-dev is indeed added.

For the second part of your question, you can avoid the error by changing laravel/homestead package version to ~4.0 or 4.0.5 to be more precise to make it compatible with your php version.

Body:
I am trying to install my composer packages using the following command:

composer install --no-dev --no-scripts

The  composer.json file looks like this (it's very similar to the standard Laravel composer file):

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.2.*",
        "doctrine/dbal": "^2.5",
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~4.0",
        "symfony/css-selector": "2.8.*|3.0.*",
        "symfony/dom-crawler": "2.8.*|3.0.*",
        "laravel/homestead": "^5.2",
        "barryvdh/laravel-ide-helper": "^2.3"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "classmap": [
            "tests/TestCase.php"
        ]
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist"
    }
}

However when I try to install it on my production machine (which runs PHP on version v5.5.9 I get the following error:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravel/homestead v5.4.0 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.3.2 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.3.1 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.3.0 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.2.4 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.2.1 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead v5.2.0 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead 5.2.3 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - laravel/homestead 5.2.2 requires php ^5.6 || ^7.0 -> your PHP version (5.5.9) does not satisfy that requirement.
    - Installation request for laravel/homestead ^5.2 -> satisfiable by laravel/homestead[5.2.2, 5.2.3, v5.2.0, v5.2.1, v5.2.4, v5.3.0, v5.3.1, v5.3.2, v5.4.0].

So my questions is as follows:

Why is homestead even being installed when I said --no-dev and homestead is a dev package?

If I did want to install Homestead on my production machine, how can I solve the above problem?


问:
Scala: increment value while mapping for lists
I have a list of strings, like

```<code>val myList = List("apple", "orange", "pear")
</code>```

I would like to transform it to a string like "1) apple 2) orange 3) pear".
I could write a for loop, but I think that in Scala there should be an one-liner for things like this.
The best one-liner I could come up with was

```<code>val myString = myList.map(s => "1) " + s).mkString(" ")
</code>```

But this results in "1) apple 1) orange 1) pear". How can increment a value while mapping a list?

答:
My Solution is:</p>

```<code>myList.map{value => s"${myList.indexOf(value)+1}) $value"}
</code>```

Body:
I have a list of strings, like

val myList = List("apple", "orange", "pear")

I would like to transform it to a string like "1) apple 2) orange 3) pear".
I could write a for loop, but I think that in Scala there should be an one-liner for things like this.
The best one-liner I could come up with was

val myString = myList.map(s => "1) " + s).mkString(" ")

But this results in "1) apple 1) orange 1) pear". How can increment a value while mapping a list?

Body:
My Solution is:

myList.map{value => s"${myList.indexOf(value)+1}) $value"}


问:
Statically linking Casablanca/CPPREST SDK
I am trying to create a Windows-based VC++ DLL (in VS 2015) that statically links to the Casablanca CPPREST SDK.  That is, I would like a single DLL output which contains the CPP REST library along with my code.

I have referred to this thread, however it seems rather dated (and has broken links):

https://katyscode.wordpress.com/2014/04/01/how-to-statically-link-the-c-rest-sdk-casablanca/

I have tried to download the Casablanca repo from GitHub and compile the "cpprestsdk140.static" project which produces a lib file.  The problem is I get a number of unresolved externals when linking it with my project.

Numerous people have commented on the unresolved link errors in the above-mentioned URL.  There are also numerous threads on Github with people saying they cannot link simple projects with the static library.

Does anyone have a clear set of steps that can help resolve this?

答:
OK, I pooled together a number of suggestions from the various threads and have the following set of steps in order to successfully link to the CPP REST static library:

Download Casablanca SDK from https://github.com/Microsoft/cpprestsdk.  (via GIT Clone or Zip).

Open the VS solution and right-click on the properties of the cpprestsdk140.static.

In the C++ -> Preprocessor definitions, add CPPREST_EXCLUDE_COMPRESSION.  The full list looks like: _NO_ASYNCRTIMP;_ASYNCRT_EXPORT;_PPLX_EXPORT;WIN32;_MBCS;_USRDLL;CPPREST_EXCLUDE_COMPRESSION;%(PreprocessorDefinitions)

In Librarian -> General -> Additional dependencies, add crypt32.lib;winhttp.lib; (See https://github.com/Microsoft/cpprestsdk/issues/344)

Press OK, then build the cpprestsdk140.static project.  You will end up with a libcpprest140d_2_9.lib (for Debug build) in the Binaries directory.

Now, in your own project:

If you have previously used the Nuget version of CPPREST, firstly ensure you remove any references in the Nuget package manager.

Right-click your project properties and go to C++ -> Additional Include Directories and enter the path for the CPPREST SDK include files.  They currently reside in cpprestsdk\Release\include.

Now go to C++ -> Preprocessor definitions, add _NO_ASYNCRTIMP (See https://github.com/Microsoft/cpprestsdk/issues/124).

Go to Linker -> Input and add libcpprest140d_2_9.lib (along with pathname, if applicable).  For the release version, it appears you also need to add crypt32.lib;winhttp.lib.

Build your project and hopefully all is well  ;)

I hope this helps someone (I'm sure it will)!


问:
Software Profiling Tools
Is there a software/profiling tool that given an algorithm and a set of inputs gives you the efficiency of the algorithm in terms of O-Notation</p>

答:
Big-O describes how the running time (and memory space) of an algorighm scales with inputs of different sizes, so such a tool would have to not accept a particular input.

If you can generate a range of inputs over a range of sizes, feed each input to the algorithm, measure the execution time (and/or memory size), and plot the result, you can then compare it against various possible big-O curves.

I don't know of any such general symbolic algorithm, and it sounds like a bit of an AI problem. Writing one would be a good exercise. There are probably algorithms which it could not analyze, but it might be able to analyze a useful subset.

Title: Software Profiling Tools


问:
Kotlin: Convert large List to sublist of set partition size
I'm looking for a function equivalent to Groovy's collate which would partition a large List into batches for processing. I did see subList which could be adapted into a similar function but wanted to check and make sure I wasn't missing an in-built or crazy simple alternative to rolling my own.

答:
With Kotlin 1.3, according to your needs, you may choose one of the following ways to solve your problem.

#1. Using chunked

```<code>fun main() {
    val list = listOf(2, 4, 3, 10, 8, 7, 9)
    val newList = list.chunked(2)
    //val newList = list.chunked(size = 2) // also works
    print(newList)
}

/*
prints:
[[2, 4], [3, 10], [8, 7], [9]]
*/
</code>```

#2. Using windowed

```<code>fun main() {
    val list = listOf(2, 4, 3, 10, 8, 7, 9)
    val newList = list.windowed(2, 2, true)
    //val newList = list.windowed(size = 2, step = 2, partialWindows = true) // also works
    println(newList)
}

/*
prints:
[[2, 4], [3, 10], [8, 7], [9]]
*/
</code>```

Body:
With Kotlin 1.3, according to your needs, you may choose one of the following ways to solve your problem.

#1. Using chunked

fun main() {
    val list = listOf(2, 4, 3, 10, 8, 7, 9)
    val newList = list.chunked(2)
    //val newList = list.chunked(size = 2) // also works
    print(newList)
}

/*
prints:
[[2, 4], [3, 10], [8, 7], [9]]
*/

#2. Using windowed

fun main() {
    val list = listOf(2, 4, 3, 10, 8, 7, 9)
    val newList = list.windowed(2, 2, true)
    //val newList = list.windowed(size = 2, step = 2, partialWindows = true) // also works
    println(newList)
}

/*
prints:
[[2, 4], [3, 10], [8, 7], [9]]
*/


问:
Trimming/ Truncating the lest letter of datavalues in bigquery
Currently this is my code in google BigQuery

```<code>SELECT *
FROM
(
    SELECT
        CAST(Serial AS integer) AS Serial,
        Latest_Use,
        Total_Hours,
        Devices_Connected
    FROM [dataworks-356fa:FirebaseArchive.PT_Results]
) AS Model_Results
JOIN
(
    SELECT
       CAST(Serial_Number AS integer) AS Serial_Number,
       Status,
       Model_Number
    FROM [dataworks-356fa:FirebaseArchive.Master_List_PT]
) AS Master_List
    ON Model_Results.Serial = Master_List.Serial_Number
</code>```

However I am not getting all of the values because some of the "Serial_Number" values end with either an 'A' or 'B', while the "serial" values do not. What do I do to either trim the values of each serial# after 5 characters or truncate the values to take out the last character.

答:
Does this work?</p>

```<code>SELECT *
FROM
(
    SELECT
        CAST(Serial AS integer) AS Serial,
        Latest_Use,
        Total_Hours,
        Devices_Connected
    FROM [dataworks-356fa:FirebaseArchive.PT_Results]
) AS Model_Results
JOIN
(
    SELECT
       CAST(Serial_Number AS integer) AS Serial_Number,
       Status,
       Model_Number
    FROM [dataworks-356fa:FirebaseArchive.Master_List_PT]
) AS Master_List
    ON Model_Results.Serial = REGEXP_EXTRACT(Master_List.Serial_Number, r'\d+')
</code>```

Body:
Currently this is my code in google BigQuery

SELECT *
FROM
(
    SELECT
        CAST(Serial AS integer) AS Serial,
        Latest_Use,
        Total_Hours,
        Devices_Connected
    FROM [dataworks-356fa:FirebaseArchive.PT_Results]
) AS Model_Results
JOIN
(
    SELECT
       CAST(Serial_Number AS integer) AS Serial_Number,
       Status,
       Model_Number
    FROM [dataworks-356fa:FirebaseArchive.Master_List_PT]
) AS Master_List
    ON Model_Results.Serial = Master_List.Serial_Number

However I am not getting all of the values because some of the "Serial_Number" values end with either an 'A' or 'B', while the "serial" values do not. What do I do to either trim the values of each serial# after 5 characters or truncate the values to take out the last character.

Body:
Does this work?

SELECT *
FROM
(
    SELECT
        CAST(Serial AS integer) AS Serial,
        Latest_Use,
        Total_Hours,
        Devices_Connected
    FROM [dataworks-356fa:FirebaseArchive.PT_Results]
) AS Model_Results
JOIN
(
    SELECT
       CAST(Serial_Number AS integer) AS Serial_Number,
       Status,
       Model_Number
    FROM [dataworks-356fa:FirebaseArchive.Master_List_PT]
) AS Master_List
    ON Model_Results.Serial = REGEXP_EXTRACT(Master_List.Serial_Number, r'\d+')


问:
Swift: how to change a class into a struct
I have written a very simple MVC program with a label and a button. The label displays the value of a counter which is incremented when the button is pressed.

The code that follows gives the model file and the view controller file. The model file is a class.
That code works.

Here is the model file:

```<code>import Foundation

protocol MVCModelDelegate {
    var message: String {get set}
}

// when I change class to struct
// delegate is set to nil
// causing the program not to update the label
class Model {
    var delegate: MVCModelDelegate?
    var counter: Int
    var message: String {
        didSet {
            delegate?.message = model.message
        }
    }

    init(counter: Int, message: String) {
        self.counter = counter
        self.message = message
    }
}

// create instance
var model = Model(counter: 0, message: "")

// counting
func incrementCounter() {
    model.counter += 1
    model.message = "Counter Value:   \(model.counter)"
}
</code>```

Here is the view controller file

```<code>import Cocoa

class ViewController: NSViewController, MVCModelDelegate {
    // communication link to the model
    var model1 = model

    var message = model.message {
        didSet {
            didUpdateModel(message: message)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.model1.delegate = self
    }

    // update display
    func didUpdateModel(message: String) {
        Label1.stringValue = model1.message
    }

    // Label
    @IBOutlet weak var Label1: NSTextField! {
        didSet {
            Label1.stringValue = " counter not started"
        }
    }

    // Button
    @IBAction func testButton(_ sender: NSButton) {
        incrementCounter()
    }
}
</code>```

Problem: I now want to change the code of the Model file to use a struct in place of a class as this very simple program does not need all the functionalities of a class. But as soon as I change class for struct. The program still runs, but the label is not updated as the delegate variable is set to nil and never gets another value.

Question: What am I missing?  The swift documentation encourages to use struct when possible. And I do not see in that code what could be a problem of transforming the class into a struct.

答:
A struct is immutable and it is not passed by reference like a class, but by value. This means that when you do

```<code>var model1 = model
</code>```

You are creating a copy of model.

modifying model1 will not propagate the changes to model, therefore all you do in incrementCounter is not reflected in your view controller.

If you want your incrementCounter to affect the viewController it must use the model in your viewController instance.

If your intention is to share the model properties and change the label value when this model is updated, struct is not the best choice.

Body:
I have written a very simple MVC program with a label and a button. The label displays the value of a counter which is incremented when the button is pressed.

The code that follows gives the model file and the view controller file. The model file is a class.
That code works.

Here is the model file:

import Foundation

protocol MVCModelDelegate {
    var message: String {get set}
}

// when I change class to struct
// delegate is set to nil
// causing the program not to update the label
class Model {
    var delegate: MVCModelDelegate?
    var counter: Int
    var message: String {
        didSet {
            delegate?.message = model.message
        }
    }

    init(counter: Int, message: String) {
        self.counter = counter
        self.message = message
    }
}

// create instance
var model = Model(counter: 0, message: "")

// counting
func incrementCounter() {
    model.counter += 1
    model.message = "Counter Value:   \(model.counter)"
}

Here is the view controller file

import Cocoa

class ViewController: NSViewController, MVCModelDelegate {
    // communication link to the model
    var model1 = model

    var message = model.message {
        didSet {
            didUpdateModel(message: message)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.model1.delegate = self
    }

    // update display
    func didUpdateModel(message: String) {
        Label1.stringValue = model1.message
    }

    // Label
    @IBOutlet weak var Label1: NSTextField! {
        didSet {
            Label1.stringValue = " counter not started"
        }
    }

    // Button
    @IBAction func testButton(_ sender: NSButton) {
        incrementCounter()
    }
}

Problem: I now want to change the code of the Model file to use a struct in place of a class as this very simple program does not need all the functionalities of a class. But as soon as I change class for struct. The program still runs, but the label is not updated as the delegate variable is set to nil and never gets another value.

Question: What am I missing?  The swift documentation encourages to use struct when possible. And I do not see in that code what could be a problem of transforming the class into a struct.

Body:
A struct is immutable and it is not passed by reference like a class, but by value. This means that when you do

var model1 = model

You are creating a copy of model.

modifying model1 will not propagate the changes to model, therefore all you do in incrementCounter is not reflected in your view controller.

If you want your incrementCounter to affect the viewController it must use the model in your viewController instance.

If your intention is to share the model properties and change the label value when this model is updated, struct is not the best choice.


问:
Unable to install Ansible in ECS optimized AMI
shell script I ran on ECS AMI

sudo yum -y install git

git clone git://github.com/ansible/ansible.git --recursive

cd ./ansible

git submodule update --init --recursive

sudo yum -y install python

sudo yum update

sudo make install

Above installation works with normal AMI, with ECS optimized AMI , I get error with make install

RuntimeError: autoconf error
make: *** [install] Error 1

答: Create your own AMI. Install what you need. Add docker and the ecs agent so it can participate in the ecs cluster. We happen to use packer to create our amis.</p>


问:
Google mobile vision not working with Yuv data?
When I give Frame.builder() a bitmap using setBitmap everything works as expected. Faces are detected and the smile probability works too. For some reason, however, .setImageData with a ByteBuffer of an NV21 format YUV image doesn't work. It doesn't throw any errors but faces are not being detected with the YuvImage data.

The i420Frame is from here: https://media.twiliocdn.com/sdk/android/conversations/releases/0.8.1/docs/com/twilio/conversations/I420Frame.html

(I'm assuming it's very similar to the i420Frame from Webrtc, if not exactly the same)

Here is the main code:

```<code>    @Override
    public void renderFrame(final I420Frame i420Frame) {
        YuvImage yuvImage = i420ToYuvImage(i420Frame.yuvPlanes, i420Frame.yuvStrides, i420Frame.width, i420Frame.height);

       // Set image data (YUV N21 format) -- NOT working. The commented bitmap line works.
        Frame frame = new Frame.Builder().setImageData(ByteBuffer.wrap(yuvImage.getYuvData()), yuvImage.getWidth(), yuvImage.getHeight(), yuvImage.getYuvFormat()).build();
       //Frame frame = new Frame.Builder().setBitmap(yuvImage).build();

       // Detect faces
       SparseArray<Face> faces = detector.detect(frame);

        if (!detector.isOperational()) {
            Log.e(TAG, "Detector is not operational!");
        }

        if (faces.size() > 0) {
            Log.i("yuv", "Smiling %: " + faces.valueAt(0).getIsSmilingProbability());
        }

       i420Frame.release();
       Log.i("yuv", "Faces detected: " + faces.size());
    }
</code>```

Here are the functions used for i420ToYuvImage (Taken from Twilio's quickstart guides). The i420 to YuvImage code was not written by me but I trust it is working properly because I took the outputted yuvimage, converted it to a jpeg, converted that to a bitmap, and the google mobile vision library was able to detect faces in the bitmap. But there is a ton of overhead in doing all those conversions. So I am trying to use the YuvImage to feed directly into the mobile vision library like above.

```<code>private YuvImage i420ToYuvImage(ByteBuffer[] yuvPlanes, int[] yuvStrides, int width, int height) {
                if (yuvStrides[0] != width) {
                    return fastI420ToYuvImage(yuvPlanes, yuvStrides, width, height);
                }
                if (yuvStrides[1] != width / 2) {
                    return fastI420ToYuvImage(yuvPlanes, yuvStrides, width, height);
                }
                if (yuvStrides[2] != width / 2) {
                    return fastI420ToYuvImage(yuvPlanes, yuvStrides, width, height);
                }

                byte[] bytes = new byte[yuvStrides[0] * height +
                        yuvStrides[1] * height / 2 +
                        yuvStrides[2] * height / 2];
                ByteBuffer tmp = ByteBuffer.wrap(bytes, 0, width * height);
                copyPlane(yuvPlanes[0], tmp);

                byte[] tmpBytes = new byte[width / 2 * height / 2];
                tmp = ByteBuffer.wrap(tmpBytes, 0, width / 2 * height / 2);

                copyPlane(yuvPlanes[2], tmp);
                for (int row = 0 ; row < height / 2 ; row++) {
                    for (int col = 0 ; col < width / 2 ; col++) {
                        bytes[width * height + row * width + col * 2]
                                = tmpBytes[row * width / 2 + col];
                    }
                }
                copyPlane(yuvPlanes[1], tmp);
                for (int row = 0 ; row < height / 2 ; row++) {
                    for (int col = 0 ; col < width / 2 ; col++) {
                        bytes[width * height + row * width + col * 2 + 1] =
                                tmpBytes[row * width / 2 + col];
                    }
                }
                return new YuvImage(bytes, NV21, width, height, null);
            }

            private YuvImage fastI420ToYuvImage(ByteBuffer[] yuvPlanes,
            int[] yuvStrides,
            int width,
            int height) {
                byte[] bytes = new byte[width * height * 3 / 2];
                int i = 0;
                for (int row = 0 ; row < height ; row++) {
                    for (int col = 0 ; col < width ; col++) {
                        bytes[i++] = yuvPlanes[0].get(col + row * yuvStrides[0]);
                    }
                }
                for (int row = 0 ; row < height / 2 ; row++) {
                    for (int col = 0 ; col < width / 2; col++) {
                        bytes[i++] = yuvPlanes[2].get(col + row * yuvStrides[2]);
                        bytes[i++] = yuvPlanes[1].get(col + row * yuvStrides[1]);
                    }
                }
                return new YuvImage(bytes, NV21, width, height, null);
            }

            private void copyPlane(ByteBuffer src, ByteBuffer dst) {
                src.position(0).limit(src.capacity());
                dst.put(src);
                dst.position(0).limit(dst.capacity());
            }
</code>```

答:
So it turns out the i420frame that Twilio sends to renderFrame() is actually rotated by 270 degrees. So calling a .setRotation fixed the issue. I had actually tried that before but I was calling .setRotation(270), which intuitively made sense to me, but after checking the documentation you have to do .setRotation(Frame.ROTATION_270) or something similar. It all works now. Here is the complete working line:</p>

```<code>Frame frame = new Frame.Builder().setImageData(ByteBuffer.wrap(yuvImage.getYuvData()), yuvImage.getWidth(), yuvImage.getHeight(), yuvImage.getYuvFormat()).setRotation(Frame.ROTATION_270).build();
</code>```

Body:
When I give Frame.builder() a bitmap using setBitmap everything works as expected. Faces are detected and the smile probability works too. For some reason, however, .setImageData with a ByteBuffer of an NV21 format YUV image doesn't work. It doesn't throw any errors but faces are not being detected with the YuvImage data.

The i420Frame is from here: https://media.twiliocdn.com/sdk/android/conversations/releases/0.8.1/docs/com/twilio/conversations/I420Frame.html

(I'm assuming it's very similar to the i420Frame from Webrtc, if not exactly the same)

Here is the main code:

    @Override
    public void renderFrame(final I420Frame i420Frame) {
        YuvImage yuvImage = i420ToYuvImage(i420Frame.yuvPlanes, i420Frame.yuvStrides, i420Frame.width, i420Frame.height);

       // Set image data (YUV N21 format) -- NOT working. The commented bitmap line works.
        Frame frame = new Frame.Builder().setImageData(ByteBuffer.wrap(yuvImage.getYuvData()), yuvImage.getWidth(), yuvImage.getHeight(), yuvImage.getYuvFormat()).build();
       //Frame frame = new Frame.Builder().setBitmap(yuvImage).build();

       // Detect faces
       SparseArray<Face> faces = detector.detect(frame);

        if (!detector.isOperational()) {
            Log.e(TAG, "Detector is not operational!");
        }

        if (faces.size() > 0) {
            Log.i("yuv", "Smiling %: " + faces.valueAt(0).getIsSmilingProbability());
        }

       i420Frame.release();
       Log.i("yuv", "Faces detected: " + faces.size());
    }

Here are the functions used for i420ToYuvImage (Taken from Twilio's quickstart guides). The i420 to YuvImage code was not written by me but I trust it is working properly because I took the outputted yuvimage, converted it to a jpeg, converted that to a bitmap, and the google mobile vision library was able to detect faces in the bitmap. But there is a ton of overhead in doing all those conversions. So I am trying to use the YuvImage to feed directly into the mobile vision library like above.

private YuvImage i420ToYuvImage(ByteBuffer[] yuvPlanes, int[] yuvStrides, int width, int height) {
                if (yuvStrides[0] != width) {
                    return fastI420ToYuvImage(yuvPlanes, yuvStrides, width, height);
                }
                if (yuvStrides[1] != width / 2) {
                    return fastI420ToYuvImage(yuvPlanes, yuvStrides, width, height);
                }
                if (yuvStrides[2] != width / 2) {
                    return fastI420ToYuvImage(yuvPlanes, yuvStrides, width, height);
                }

                byte[] bytes = new byte[yuvStrides[0] * height +
                        yuvStrides[1] * height / 2 +
                        yuvStrides[2] * height / 2];
                ByteBuffer tmp = ByteBuffer.wrap(bytes, 0, width * height);
                copyPlane(yuvPlanes[0], tmp);

                byte[] tmpBytes = new byte[width / 2 * height / 2];
                tmp = ByteBuffer.wrap(tmpBytes, 0, width / 2 * height / 2);

                copyPlane(yuvPlanes[2], tmp);
                for (int row = 0 ; row < height / 2 ; row++) {
                    for (int col = 0 ; col < width / 2 ; col++) {
                        bytes[width * height + row * width + col * 2]
                                = tmpBytes[row * width / 2 + col];
                    }
                }
                copyPlane(yuvPlanes[1], tmp);
                for (int row = 0 ; row < height / 2 ; row++) {
                    for (int col = 0 ; col < width / 2 ; col++) {
                        bytes[width * height + row * width + col * 2 + 1] =
                                tmpBytes[row * width / 2 + col];
                    }
                }
                return new YuvImage(bytes, NV21, width, height, null);
            }

            private YuvImage fastI420ToYuvImage(ByteBuffer[] yuvPlanes,
            int[] yuvStrides,
            int width,
            int height) {
                byte[] bytes = new byte[width * height * 3 / 2];
                int i = 0;
                for (int row = 0 ; row < height ; row++) {
                    for (int col = 0 ; col < width ; col++) {
                        bytes[i++] = yuvPlanes[0].get(col + row * yuvStrides[0]);
                    }
                }
                for (int row = 0 ; row < height / 2 ; row++) {
                    for (int col = 0 ; col < width / 2; col++) {
                        bytes[i++] = yuvPlanes[2].get(col + row * yuvStrides[2]);
                        bytes[i++] = yuvPlanes[1].get(col + row * yuvStrides[1]);
                    }
                }
                return new YuvImage(bytes, NV21, width, height, null);
            }

            private void copyPlane(ByteBuffer src, ByteBuffer dst) {
                src.position(0).limit(src.capacity());
                dst.put(src);
                dst.position(0).limit(dst.capacity());
            }

Body:
So it turns out the i420frame that Twilio sends to renderFrame() is actually rotated by 270 degrees. So calling a .setRotation fixed the issue. I had actually tried that before but I was calling .setRotation(270), which intuitively made sense to me, but after checking the documentation you have to do .setRotation(Frame.ROTATION_270) or something similar. It all works now. Here is the complete working line:

Frame frame = new Frame.Builder().setImageData(ByteBuffer.wrap(yuvImage.getYuvData()), yuvImage.getWidth(), yuvImage.getHeight(), yuvImage.getYuvFormat()).setRotation(Frame.ROTATION_270).build();


问:
Is it possible to use .exceptionCount(true) twice?
i have a problem, I want to count the different elements of bar and num associated with foo

```<code>var data = crossfilter([
{ foo: 'one', bar: 'A', num: '1' },
{ foo: 'two', bar: 'B', num: '2' },
{ foo: 'three', bar: 'A', num: '3' },
{ foo: 'one', bar: 'B', num: '3' },
{ foo: 'one', bar: 'A', num: '2' },
{ foo: 'two', bar: 'B', num: '2' },
]);
</code>```

ie, I want to get, for example:

```<code>[ { key: 'one', value: { exceptionCount: 2, exceptionCount2: 3 },    // 'bar' dimension has 2 values: 'A' and 'B', and has 3 values: '1' and '2' and '3'
{ key: 'two', value: { exceptionCount: 1, exceptionCount2: 1 },    // 'bar' dimension has 1 value: 'B', '2'
{ key: 'three', value: { exceptionCount: 1 , exceptionCount2: 1} ] // 'bar' dimension has 1 value: 'A', '3'
</code>```

I have use of the reductio library with exceptionCount to separate for num and bar, but I could not join both associated with only foo.

Can you help me, please

答:
Yes, the reductio.value method lets you put multiple reducers of the same type on a group. There is an example in the README using exceptionSum that can be adapted to use exceptionCount. Your group structure will change a bit.

https://github.com/crossfilter/reductio#aggregations-standard-aggregations-reductio-b-value-b-i-propertyname-i-

Body:
i have a problem, I want to count the different elements of bar and num associated with foo

var data = crossfilter([
{ foo: 'one', bar: 'A', num: '1' },
{ foo: 'two', bar: 'B', num: '2' },
{ foo: 'three', bar: 'A', num: '3' },
{ foo: 'one', bar: 'B', num: '3' },
{ foo: 'one', bar: 'A', num: '2' },
{ foo: 'two', bar: 'B', num: '2' },
]);

ie, I want to get, for example:

[ { key: 'one', value: { exceptionCount: 2, exceptionCount2: 3 },    // 'bar' dimension has 2 values: 'A' and 'B', and has 3 values: '1' and '2' and '3'
{ key: 'two', value: { exceptionCount: 1, exceptionCount2: 1 },    // 'bar' dimension has 1 value: 'B', '2'
{ key: 'three', value: { exceptionCount: 1 , exceptionCount2: 1} ] // 'bar' dimension has 1 value: 'A', '3'

I have use of the reductio library with exceptionCount to separate for num and bar, but I could not join both associated with only foo.

Can you help me, please


问:
java - android UDP unreliability
I am having extreme UDP packet losses with Android and it does not make sense. The situation is as follows:

PC running java client connected to home network

Phone running java server (android) connected to home network

Home router is a brand new WRT1900ac. Network has internet connectivity.

UDP packets are small (< 15 bytes)

Symptoms:

If PC sends UDP packet to another PC (both on same network) it works very well (almost no packets lost).

If Android sends UDP packet to PC on the same network it also works very well (almost no packets lost).

If PC sends UDP to Android on the same network I get extreme packet losses (50% of the time or more - but it varies).

Most times I am forced to send the packet like 10 times to get one through. Other times all get through with quite some delay. Very strange behavior that only happens on the receiving end of android. If I replace android with pc running the same code on java or simply receiving the packet through Packet Sender's UDP server I have no loss issues. Another thing I noticed is that if instead of going through the router I go through another access point that has no internet connectivity or no other clients performance seems to dramatically improve. This is expected, but my question is why Android's receiving end is seeing such poor performance and losing so many packets. When Android is replaced with another PC running the same code and on the same network there are no issues. Android also has no issues sending out the packets (no packets are lost). Therefore it has to be something else android related on the receiving end...

I have also tried replacing the PC code with Packet Sender and I get the same results. The problem seems to be Android's receiving end. I run the same UDP code on the PC side and on android.

The UDP sending code is simple:

```<code>public void sendMessage(String message)
{
    try {
        DatagramSocket ds = new DatagramSocket();
        DatagramPacket dp;
        InetAddress local = InetAddress.getByName(ipPool);
        dp = new DatagramPacket(message.getBytes(), message.length(), local, port);
        ds.setBroadcast(true);
        ds.send(dp);
        ds.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
</code>```

The UDP receiving code on android lives in a UDP server class:

```<code>public class UDP_Server
{
    CommandParser commandParser;

    public UDP_Server(MainActivity mainActivity)
    {
        Log.i("Udp tutorial", "---------------------------Starting UDP SERVER");

        commandParser = new CommandParser(mainActivity);
        String text;
        int server_port = 9876;
        try
        {
            DatagramSocket s = new DatagramSocket(server_port);
            s.setBroadcast(true);
            //s.setReceiveBufferSize(163840);

            while (true)
            {
                byte[] message = new byte[1024];
                DatagramPacket p = new DatagramPacket(message, message.length);

                s.receive(p);
                text = new String(message, 0, p.getLength());
                Log.d("Udp tutorial","message:" + text);
                //commandParser.parseCommand(text);
                //s.close();
            }
        } catch (SocketException e)
        {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
</code>```

The UDPServer.java class is instantiated through the main activity "onCreate()" method:

```<code>    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        wm = (WifiManager) getSystemService(WIFI_SERVICE);

        Log.i("Udp tutorial", "---------------------------HERE 1");
        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                UDP_Server svr = new UDP_Server(MainActivity.this);
            }
        });

        thread.setPriority(Thread.MAX_PRIORITY);
        thread.start();
//        TCPServer server = new TCPServer();
    }
</code>```

答:
I had catastrophic results with some Android devices sending a file to a TFTP (based on UDP) server over WiFi, but it seemed to work well with other Android devices.

Data blocks (from the device to the server) were properly sent, but ack blocks (from the server to the device) seemed to be lost in limbo.

Turns out I had to acquire a multicast lock for those faulty devices to work properly (credits to https://www.b4x.com/android/forum/threads/enable-multicast.43321/#post-263242)

```<code>WifiManager wifi = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();

...

multicastLock.release();
</code>```

Hope this helps.

Title: java - android UDP unreliability

Body:
I am having extreme UDP packet losses with Android and it does not make sense. The situation is as follows:

PC running java client connected to home network

Phone running java server (android) connected to home network

Home router is a brand new WRT1900ac. Network has internet connectivity.

UDP packets are small (< 15 bytes)

Symptoms:

If PC sends UDP packet to another PC (both on same network) it works very well (almost no packets lost).

If Android sends UDP packet to PC on the same network it also works very well (almost no packets lost).

If PC sends UDP to Android on the same network I get extreme packet losses (50% of the time or more - but it varies).

Most times I am forced to send the packet like 10 times to get one through. Other times all get through with quite some delay. Very strange behavior that only happens on the receiving end of android. If I replace android with pc running the same code on java or simply receiving the packet through Packet Sender's UDP server I have no loss issues. Another thing I noticed is that if instead of going through the router I go through another access point that has no internet connectivity or no other clients performance seems to dramatically improve. This is expected, but my question is why Android's receiving end is seeing such poor performance and losing so many packets. When Android is replaced with another PC running the same code and on the same network there are no issues. Android also has no issues sending out the packets (no packets are lost). Therefore it has to be something else android related on the receiving end...

I have also tried replacing the PC code with Packet Sender and I get the same results. The problem seems to be Android's receiving end. I run the same UDP code on the PC side and on android.

The UDP sending code is simple:

public void sendMessage(String message)
{
    try {
        DatagramSocket ds = new DatagramSocket();
        DatagramPacket dp;
        InetAddress local = InetAddress.getByName(ipPool);
        dp = new DatagramPacket(message.getBytes(), message.length(), local, port);
        ds.setBroadcast(true);
        ds.send(dp);
        ds.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

The UDP receiving code on android lives in a UDP server class:

public class UDP_Server
{
    CommandParser commandParser;

    public UDP_Server(MainActivity mainActivity)
    {
        Log.i("Udp tutorial", "---------------------------Starting UDP SERVER");

        commandParser = new CommandParser(mainActivity);
        String text;
        int server_port = 9876;
        try
        {
            DatagramSocket s = new DatagramSocket(server_port);
            s.setBroadcast(true);
            //s.setReceiveBufferSize(163840);

            while (true)
            {
                byte[] message = new byte[1024];
                DatagramPacket p = new DatagramPacket(message, message.length);

                s.receive(p);
                text = new String(message, 0, p.getLength());
                Log.d("Udp tutorial","message:" + text);
                //commandParser.parseCommand(text);
                //s.close();
            }
        } catch (SocketException e)
        {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

The UDPServer.java class is instantiated through the main activity "onCreate()" method:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        wm = (WifiManager) getSystemService(WIFI_SERVICE);

        Log.i("Udp tutorial", "---------------------------HERE 1");
        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                UDP_Server svr = new UDP_Server(MainActivity.this);
            }
        });

        thread.setPriority(Thread.MAX_PRIORITY);
        thread.start();
//        TCPServer server = new TCPServer();
    }

Body:
I had catastrophic results with some Android devices sending a file to a TFTP (based on UDP) server over WiFi, but it seemed to work well with other Android devices.

Data blocks (from the device to the server) were properly sent, but ack blocks (from the server to the device) seemed to be lost in limbo.

Turns out I had to acquire a multicast lock for those faulty devices to work properly (credits to https://www.b4x.com/android/forum/threads/enable-multicast.43321/#post-263242)

WifiManager wifi = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();

...

multicastLock.release();

Hope this helps.