问:
How to access DOM of all tabs from background script in Chrome extension?
My current code logs Here you go, 1 cookie. in the console of the active tab whenever I click the extension's icon.

How do I make it log the HTML of all tabs, instead?

manifest.json ↓

{
  "manifest_version": 2,
  "name": "My Extension",
  "permissions": [
    "tabs", "activeTab"
  ],
  "background": {
    "persistent": false,
    "scripts": [
      "background.js"
    ]
  },
  "version": "0.1",
  "icons": {
    "16": "icon16.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "browser_action": {
    "default_icon": "icon16.png",
    "default_title": "My Extension"
  },
  "content_scripts": [
    {
      "matches": [
        "<all_urls>"
      ],
      "js": [
        "script.js"
      ]
    }
  ]
}
```

<blockquote>
  <p>onClick.js ↓</p>
</blockquote>

<pre class="lang-js prettyprint-override"><code>chrome.runtime.sendMessage('Please send cookies!', async response => {
  console.log(response);
});
</code>```

background.js ↓

chrome.browserAction.onClicked.addListener(tab => {
  chrome.tabs.executeScript(null, { file: 'onClick.js' });
});

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
  sendResponse('Here you go, 1 cookie.');
});
```

<blockquote>
  <p>script.js ↓</p>
</blockquote>

<pre class="lang-js prettyprint-override"><code>// nothing
</code>```

答:
I made an extension that performs a global find-and-replace in all tabs in all inputs and textareas upon enter press and upon tab load.

The Github respository is here.

popup.html ↓

<!DOCTYPE html>

  <title>Global Replace All</title>

  Find:
    <input type="text" id="find" />

  Replace:
    <input type="text" id="replace" />

```

<blockquote>
  <p>popup.js ↓</p>
</blockquote>

<pre class="lang-js prettyprint-override"><code>'use strict';

const findBox = document.getElementById('find');
const replaceBox = document.getElementById('replace');

chrome.runtime.sendMessage({ message: 'get' }, response => {
  findBox.value = response.find;
  replaceBox.value = response.replace;
});

document.getElementById('find').addEventListener('input', () => {
  const find = findBox.value;
  chrome.runtime.sendMessage({ message: 'setFind', find });
});

document.getElementById('replace').addEventListener('input', () => {
  const replace = replaceBox.value;
  chrome.runtime.sendMessage({ message: 'setReplace', replace });
});

document.addEventListener('keypress', function (e) {
  if (e.keyCode == 13) {
    chrome.runtime.sendMessage({ message: 'replaceAll' });
    window.close();
  }
});
</code>```

script.js ↓

'use strict';

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.message == 'replaceAll') {
    replaceAll(request.find, request.replace);
    sendResponse({ message: 'done ' });
  }
});

window.onload = function () {
  chrome.runtime.sendMessage({ message: 'tabLoaded' }, response => {
    replaceAll(response.find, response.replace);
  });
}

function replaceAll(find, replace) {
  console.log(`Replacing all << ${find} >> with << ${replace} >>.`);
  let myRegExp = new RegExp(find, 'g');
  [].forEach.call(
    document.querySelectorAll('input, textarea'),
    function (e) { e.value = e.value.replace(myRegExp, replace); }
  );
}
```

<blockquote>
  <p>background.js ↓</p>
</blockquote>

<pre class="lang-js prettyprint-override"><code>'use strict';

let find = '';
let replace = '';

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  switch (request.message) {
    case 'get':
      sendResponse({ find, replace });
      break;
    case 'setFind':
      find = request.find;
      break;
    case 'setReplace':
      replace = request.replace;
      break;
    case 'tabLoaded':
      sendResponse({ find, replace });
      break;
    case 'replaceAll':
      return replaceAll();
      break;
  }
});

function replaceAll() {
  new Promise(async resolve => {
    let tabList = [];
    chrome.windows.getAll({ populate: true }, windows => {
      windows.forEach(window => {
        window.tabs.forEach(tab => {
          tabList.push(tab);
        });
      });
      resolve(tabList);
    });
  }).then(tabList => {
    tabList.forEach(tab => chrome.tabs.sendMessage(tab.id, { message: 'replaceAll', find, replace }));
  });
  return true; // this means its async
}
</code>```

manifest.json ↓

{
  "manifest_version": 2,
  "name": "Global Replace All",
  "permissions": [
    "tabs", "activeTab"
  ],
  "background": {
    "persistent": false,
    "scripts": [
      "background.js"
    ]
  },
  "version": "0.1",
  "icons": {
    "16": "icon16.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "browser_action": {
    "default_icon": "icon16.png",
    "default_title": "Global Replace All",
    "default_popup": "popup.html"
  },
  "content_scripts": [
    {
      "matches": [
        "<all_urls>"
      ],
      "js": [
        "script.js"
      ]
    }
  ]
}
```

Body:
My current code logs Here you go, 1 cookie. in the console of the active tab whenever I click the extension's icon.

How do I make it log the HTML of all tabs, instead?

manifest.json ↓

{
  "manifest_version": 2,
  "name": "My Extension",
  "permissions": [
    "tabs", "activeTab"
  ],
  "background": {
    "persistent": false,
    "scripts": [
      "background.js"
    ]
  },
  "version": "0.1",
  "icons": {
    "16": "icon16.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "browser_action": {
    "default_icon": "icon16.png",
    "default_title": "My Extension"
  },
  "content_scripts": [
    {
      "matches": [
        "<all_urls>"
      ],
      "js": [
        "script.js"
      ]
    }
  ]
}

onClick.js ↓

chrome.runtime.sendMessage('Please send cookies!', async response => {
  console.log(response);
});

background.js ↓

chrome.browserAction.onClicked.addListener(tab => {
  chrome.tabs.executeScript(null, { file: 'onClick.js' });
});

chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
  sendResponse('Here you go, 1 cookie.');
});

script.js ↓

// nothing

Body:
I made an extension that performs a global find-and-replace in all tabs in all inputs and textareas upon enter press and upon tab load.

The Github respository is here.

popup.html ↓

<!DOCTYPE html>
<header>
  <title>Global Replace All</title>
</header>

<body>
  <label>Find:
    <input type="text" id="find" />
  </label>
  <label>Replace:
    <input type="text" id="replace" />
  </label>
  <script src="popup.js"></script>
</body>

</html>

popup.js ↓

'use strict';

const findBox = document.getElementById('find');
const replaceBox = document.getElementById('replace');

chrome.runtime.sendMessage({ message: 'get' }, response => {
  findBox.value = response.find;
  replaceBox.value = response.replace;
});

document.getElementById('find').addEventListener('input', () => {
  const find = findBox.value;
  chrome.runtime.sendMessage({ message: 'setFind', find });
});

document.getElementById('replace').addEventListener('input', () => {
  const replace = replaceBox.value;
  chrome.runtime.sendMessage({ message: 'setReplace', replace });
});

document.addEventListener('keypress', function (e) {
  if (e.keyCode == 13) {
    chrome.runtime.sendMessage({ message: 'replaceAll' });
    window.close();
  }
});

script.js ↓

'use strict';

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.message == 'replaceAll') {
    replaceAll(request.find, request.replace);
    sendResponse({ message: 'done ' });
  }
});

window.onload = function () {
  chrome.runtime.sendMessage({ message: 'tabLoaded' }, response => {
    replaceAll(response.find, response.replace);
  });
}

function replaceAll(find, replace) {
  console.log(`Replacing all << ${find} >> with << ${replace} >>.`);
  let myRegExp = new RegExp(find, 'g');
  [].forEach.call(
    document.querySelectorAll('input, textarea'),
    function (e) { e.value = e.value.replace(myRegExp, replace); }
  );
}

background.js ↓

'use strict';

let find = '';
let replace = '';

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  switch (request.message) {
    case 'get':
      sendResponse({ find, replace });
      break;
    case 'setFind':
      find = request.find;
      break;
    case 'setReplace':
      replace = request.replace;
      break;
    case 'tabLoaded':
      sendResponse({ find, replace });
      break;
    case 'replaceAll':
      return replaceAll();
      break;
  }
});

function replaceAll() {
  new Promise(async resolve => {
    let tabList = [];
    chrome.windows.getAll({ populate: true }, windows => {
      windows.forEach(window => {
        window.tabs.forEach(tab => {
          tabList.push(tab);
        });
      });
      resolve(tabList);
    });
  }).then(tabList => {
    tabList.forEach(tab => chrome.tabs.sendMessage(tab.id, { message: 'replaceAll', find, replace }));
  });
  return true; // this means its async
}

manifest.json ↓

{
  "manifest_version": 2,
  "name": "Global Replace All",
  "permissions": [
    "tabs", "activeTab"
  ],
  "background": {
    "persistent": false,
    "scripts": [
      "background.js"
    ]
  },
  "version": "0.1",
  "icons": {
    "16": "icon16.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "browser_action": {
    "default_icon": "icon16.png",
    "default_title": "Global Replace All",
    "default_popup": "popup.html"
  },
  "content_scripts": [
    {
      "matches": [
        "<all_urls>"
      ],
      "js": [
        "script.js"
      ]
    }
  ]
}


来源: stackexchange

问:
Sorting a vector with pointer at object C++
If anyone can help I would be very grateful.
How do i sort this vector:

vector<Person*>person

by this criterium:

Surname

I have already tried it using set but it removes object if there is more than 2 objects with same Surname

there are lot of string variables, and I need to sort it by

Surname

and then if surnames are the same, then I need to sort them by

Name

and also it sorts by hexadecimal value of that pointer...
EDIT:
More code as you ask:

```<code>for (pChild = pRoot->FirstChildElement("Member"); pChild != NULL; pChild = pChild->NextSiblingElement())
    {
        string Surname = pChild->Attribute("surname");
        string Name = pChild->Attribute("name");
        string DateOfBirth = pChild->Attribute("dateofbirth");
        person.push_back(new Person(Surname, Name, DateOfBirth));
    }
</code>```

答: Without you showing more of your code, it is hard to help you, but I would look at the documentation for std::sort() as you can create custom operators to sort your vector.</p>

ContentLicense: CC BY-SA 4.0

Body:
If anyone can help I would be very grateful.
How do i sort this vector:

vector<Person*>person

by this criterium:

Surname

I have already tried it using set but it removes object if there is more than 2 objects with same Surname

there are lot of string variables, and I need to sort it by

Surname

and then if surnames are the same, then I need to sort them by

Name

and also it sorts by hexadecimal value of that pointer...
EDIT:
More code as you ask:

for (pChild = pRoot->FirstChildElement("Member"); pChild != NULL; pChild = pChild->NextSiblingElement())
    {
        string Surname = pChild->Attribute("surname");
        string Name = pChild->Attribute("name");
        string DateOfBirth = pChild->Attribute("dateofbirth");
        person.push_back(new Person(Surname, Name, DateOfBirth));
    }


问:
Get Data from firebase for swift
I have below code to get data from my firebase database

```<code>db.collection("users").getDocuments() { (querySnapshot, err) in
        if let err = err {
            print("Error getting documents: \(err)")
        } else {
            print("starting name display")
            for document in (querySnapshot?.documents)! {
                let documentUserId = document.get("uid") as?String
                let temp = document.data()["displayName"]
                print(temp)
            }
          }
        }
</code>```

The print statement displays as optional("test name")
Why am i keep getting optional in my string. Same displays on the screen as well.

答:
You need to un-wrap because it's an Optional. Means it could have a value or it could not have a value. So this is one method to handle it:

let temp = document.data()["displayName"] ?? ""
print(temp)
```

You could also use if let or guard let statements if you need to handle the cases where the value is actually empty.

Note: Take a look at the basics of swift. There is a separate section for Optionals.

Title: Get Data from firebase for swift

Body:
I have below code to get data from my firebase database

db.collection("users").getDocuments() { (querySnapshot, err) in
        if let err = err {
            print("Error getting documents: \(err)")
        } else {
            print("starting name display")
            for document in (querySnapshot?.documents)! {
                let documentUserId = document.get("uid") as?String
                let temp = document.data()["displayName"]
                print(temp)
            }
          }
        }

The print statement displays as optional("test name")
Why am i keep getting optional in my string. Same displays on the screen as well.

Body:
You need to un-wrap because it's an Optional. Means it could have a value or it could not have a value. So this is one method to handle it:

let temp = document.data()["displayName"] ?? ""
print(temp)

You could also use if let or guard let statements if you need to handle the cases where the value is actually empty.

Note: Take a look at the basics of swift. There is a separate section for Optionals.


问:
creating iPhone draggable objects
I need to figure out how in the world do I create object instances (an image) and place them on the screen and have it draggable. I know how to draw an image (png) onto the screen, but how do I make it draggable? </p>

答: Create sublclasses of UIView where you override the touchesEnded method. Inside this method alter the coordinates of the view to match those of the most recent UITouch, and that will give you basic draggable views.</p>

ContentLicense: CC BY-SA 2.5

Title: creating iPhone draggable objects

ContentLicense: CC BY-SA 3.0


问:
How to iterate over all values of an Enum including any nested Enums?
Imagine one has two classes derived from Enum, e.g.

```<code>class Color(Enum):
    blue = 'blue'
    red = 'red'

class Properties(Enum):
    height = 'h'
    weight = 'w'
    colors = Color

</code>```

What is the best way to (probably recursively) iterate over all Enum-labels of a nested Enum like Properties, including the ones of Enum-members like Properties.colors in the example above (i.e. including  Color.blue and Color.red)? Checking for the type of the value?

答:
Here's a quick example that just prints them out.  I'll leave it as an exercise to the reader to make this a generic generator or whatever applies to the actual use case.  :)</p>

```<code>>>> from typing import Type
>>> def print_enum(e: Type[Enum]) -> None:
...     for p in e:
...         try:
...             assert(issubclass(p.value, Enum))
...             print_enum(p.value)
...         except (AssertionError, TypeError):
...             print(p)
...
>>> print_enum(Properties)
Properties.height
Properties.weight
Color.blue
Color.red
</code>```

Body:
Imagine one has two classes derived from Enum, e.g.

class Color(Enum):
    blue = 'blue'
    red = 'red'

class Properties(Enum):
    height = 'h'
    weight = 'w'
    colors = Color

What is the best way to (probably recursively) iterate over all Enum-labels of a nested Enum like Properties, including the ones of Enum-members like Properties.colors in the example above (i.e. including  Color.blue and Color.red)? Checking for the type of the value?

Body:
Here's a quick example that just prints them out.  I'll leave it as an exercise to the reader to make this a generic generator or whatever applies to the actual use case.  :)

>>> from typing import Type
>>> def print_enum(e: Type[Enum]) -> None:
...     for p in e:
...         try:
...             assert(issubclass(p.value, Enum))
...             print_enum(p.value)
...         except (AssertionError, TypeError):
...             print(p)
...
>>> print_enum(Properties)
Properties.height
Properties.weight
Color.blue
Color.red


问:
ld64 segprot on MacOS Catalina not working?
I want to create a binary on MacOS Catalina (64 bit) with a data segment that can be made executable (see here for details) but is not executable from the start.

I make my binary with

gcc -nostdlib -segprot __DATA rwx rw- ....
```

<p>I also created an object file with gcc and then called ld directly. The ld version is</p>

<pre class="lang-sh prettyprint-override"><code>$ ld -v
@(#)PROGRAM:ld  PROJECT:ld64-530
BUILD 18:57:17 Dec 13 2019
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 11.0.0, (clang-1100.0.33.17) (static support for 23, runtime is 23)
TAPI support using: Apple TAPI version 11.0.0 (tapi-1100.0.11)
</code>```

That should make the data segment initially RW, but allow me to use mprotect to extend permission in that segment to RWX.

However, I notice that the __DATA segment is RW for initial and max permission:

```<code>$ otool -l jonesforth
.
.
.
Load command 2
      cmd LC_SEGMENT_64
  cmdsize 312
  segname __DATA
   vmaddr 0x0000000100001000
   vmsize 0x0000000000024000
  fileoff 4096
 filesize 4096
  maxprot 0x00000003
 initprot 0x00000003
   nsects 3
    flags 0x0
Section
.
.
.

</code>```

Is there something I'm missing? The darwin documentation here says:

```<code>-segprot name max init (32-bit only)

              Specifies the maximum and initial virtual memory  protection  of
              the  named segment, name, to be max and init ,respectively.  The
              values for max and init are any combination  of  the  characters
              `r'  (for  read), `w' (for write), `x' (for execute) and '-' (no
              access).  The default is `rwx' for the  maximum  protection  for
              all segments for PowerPC architecures and `rw` for the all Intel
              architecures.  The default for the initial  protection  for  all
              segments  is  `rw'  unless  the segment contains a section which
              contains some machine instructions, in which  case  the  default
              for  the initial protection is `rwx' (and for Intel architecures
              it also sets the maximum protection to `rwx' in this case).  The
              default for the initial protection for the ``__TEXT'' segment is
              `rx' (not writable).
</code>```

Of course, that the darwin (32 bit only) documentation but it's the only thing I found.
I suspect that either gcc does not 'properly' support the darwin protection syntax, or it's broken, or things in darwin changed from x86 to x64.

Any pointers would be great, thanks in advance.

答:
Yes, something did happen on March 18:

Apple committed a change that makes ld always set maxprot = initprot for non-i386 architectures, so including x64, ie Catalina. It's unclear whether this was intentional, it's at odds with the ld manpage.

One workaround is of course to set the desired protection level for the entire segment in initprot. One can probably move the desired data/code into a separate segment if one wants to have finer grained control.

Another workaround, thanks to the comment from Darfink: One can also change the linker  or modify the desired maxprot after ld runs. Darfink pointed out his ld64 wrapper, a python script, to automate this.

Body:
I want to create a binary on MacOS Catalina (64 bit) with a data segment that can be made executable (see here for details) but is not executable from the start.

I make my binary with

gcc -nostdlib -segprot __DATA rwx rw- ....

I also created an object file with gcc and then called ld directly. The ld version is

$ ld -v
@(#)PROGRAM:ld  PROJECT:ld64-530
BUILD 18:57:17 Dec 13 2019
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 11.0.0, (clang-1100.0.33.17) (static support for 23, runtime is 23)
TAPI support using: Apple TAPI version 11.0.0 (tapi-1100.0.11)

That should make the data segment initially RW, but allow me to use mprotect to extend permission in that segment to RWX.

However, I notice that the __DATA segment is RW for initial and max permission:

$ otool -l jonesforth
.
.
.
Load command 2
      cmd LC_SEGMENT_64
  cmdsize 312
  segname __DATA
   vmaddr 0x0000000100001000
   vmsize 0x0000000000024000
  fileoff 4096
 filesize 4096
  maxprot 0x00000003
 initprot 0x00000003
   nsects 3
    flags 0x0
Section
.
.
.

Is there something I'm missing? The darwin documentation here says:

-segprot name max init (32-bit only)

              Specifies the maximum and initial virtual memory  protection  of
              the  named segment, name, to be max and init ,respectively.  The
              values for max and init are any combination  of  the  characters
              `r'  (for  read), `w' (for write), `x' (for execute) and '-' (no
              access).  The default is `rwx' for the  maximum  protection  for
              all segments for PowerPC architecures and `rw` for the all Intel
              architecures.  The default for the initial  protection  for  all
              segments  is  `rw'  unless  the segment contains a section which
              contains some machine instructions, in which  case  the  default
              for  the initial protection is `rwx' (and for Intel architecures
              it also sets the maximum protection to `rwx' in this case).  The
              default for the initial protection for the ``__TEXT'' segment is
              `rx' (not writable).

Of course, that the darwin (32 bit only) documentation but it's the only thing I found.
I suspect that either gcc does not 'properly' support the darwin protection syntax, or it's broken, or things in darwin changed from x86 to x64.

Any pointers would be great, thanks in advance.


问:
How to use styled from react-emotion with HighchartsReact?
I want to wrap HighchartsReact with HighChartWrapper using styled from react-emotion.

Below is the pseudo-code that I am trying.

```<code>import HighchartsReact from 'highcharts-react-official';
import styled from 'react-emotion';

const HighChartWrapper = styled(HighchartsReact)`
/* some styles here */
.highcharts-background {
    fill: white !important;
  }
`;

<HighChartWrapper highcharts={Highcharts} options={chartData} />
</code>```

The styles are not working. I am aware that styled can style any component as long as it accepts a className prop.

So does anyone has a working example or a workaround for this?

答:
You can wrap your chart component and pass className prop by containerProps, for example:

```<code>const Chart = (props) => {
  const [options] = useState({
    ...
  });

  return (
    <HighchartsReact
      highcharts={Highcharts}
      options={options}
      containerProps={{ className: props.className }}
    />;
  );
};

const HighChartWrapper = styled(Chart)`
/* some styles here */
  .highcharts-plot-border {
    fill: black !important;
  }
`;
</code>```

Live demo: https://codesandbox.io/s/highcharts-react-demo-vosjm?file=/demo.jsx

Docs: https://github.com/highcharts/highcharts-react#options-details

Body:
I want to wrap HighchartsReact with HighChartWrapper using styled from react-emotion.

Below is the pseudo-code that I am trying.

import HighchartsReact from 'highcharts-react-official';
import styled from 'react-emotion';

const HighChartWrapper = styled(HighchartsReact)`
/* some styles here */
.highcharts-background {
    fill: white !important;
  }
`;

<HighChartWrapper highcharts={Highcharts} options={chartData} />

The styles are not working. I am aware that styled can style any component as long as it accepts a className prop.

So does anyone has a working example or a workaround for this?

Body:
You can wrap your chart component and pass className prop by containerProps, for example:

const Chart = (props) => {
  const [options] = useState({
    ...
  });

  return (
    <HighchartsReact
      highcharts={Highcharts}
      options={options}
      containerProps={{ className: props.className }}
    />;
  );
};

const HighChartWrapper = styled(Chart)`
/* some styles here */
  .highcharts-plot-border {
    fill: black !important;
  }
`;

Live demo: https://codesandbox.io/s/highcharts-react-demo-vosjm?file=/demo.jsx

Docs: https://github.com/highcharts/highcharts-react#options-details


问:
Swagger Editor 3.8 examples not working for reference array schema
This question is a follow-up to this similar one - as @Helen requested a new question be asked.

It seems an array type schema only accepts "example", not "examples".  The following schema produces an error on the editor.swagger.io site:

```<code>info:
  title: Example Inc. REST API version 1.0
  version: '1.0'
openapi: 3.0.0
components:
  schemas:
    user_reference:
      properties:
        comment:
          type: string
        middle_name:
          type: string
        domain:
          pattern: '^[0-9A-Za-z][0-9A-Za-z.-]*$'
          type: string
        id:
          minimum: 1
          type: integer
        first_name:
          type: string
        last_name:
          type: string
        username:
          pattern: '^[0-9A-Za-z_.@-]+$'
          type: string
      type: object
    owners_reference_list:
      type: array
      items:
        $ref: '#/components/schemas/user_reference'
      examples:
        by_site:
          summary: Access by site and username
          value:
            - domain: example.com
              username: jsmith
        by_id:
          value:
            - id: 14
          summary: Access by id
        by_other:
          summary: Access by other attributes
          value:
            - middle_name: X.
              last_name: Smith
              comments: Standard user
              first_name: John
  responses:
    ok:
      content:
        application/json:
          schema:
            type: string
      description: |
        ...
paths:
  /users:
    description: |
      A user account ...
    get:
      parameters:
        - description: |
            ...
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/owners_reference_list'
          name: owners_ref
          required: false
          in: query
      responses:
        '200':
          $ref: '#/components/responses/ok'
</code>```

But if I replace the "examples" attribute with "example", e.g.:

```<code>owners_reference_list:
  type: array
  items:
    $ref: '#/components/schemas/user_reference'
  example:
        - domain: example.com
          username: jsmith
</code>```

then it works fine.

The referenced question is answered that "examples" is supported in Swagger Editor 3.6.21, and the comment by @Helen says that the editor.swagger.io site is using version 3.8.3.

答:
Schemas do not support multiple examples, they only support a single example.

Multiple examples can only be used in:

request bodies: requestBody.content.<media-type>.examples

responses: responses..content.<media-type>.examples

parameters that use the content keyword: <parameter>.content.<media-type>.examples

Body:
This question is a follow-up to this similar one - as @Helen requested a new question be asked.

It seems an array type schema only accepts "example", not "examples".  The following schema produces an error on the editor.swagger.io site:

info:
  title: Example Inc. REST API version 1.0
  version: '1.0'
openapi: 3.0.0
components:
  schemas:
    user_reference:
      properties:
        comment:
          type: string
        middle_name:
          type: string
        domain:
          pattern: '^[0-9A-Za-z][0-9A-Za-z.-]*$'
          type: string
        id:
          minimum: 1
          type: integer
        first_name:
          type: string
        last_name:
          type: string
        username:
          pattern: '^[0-9A-Za-z_.@-]+$'
          type: string
      type: object
    owners_reference_list:
      type: array
      items:
        $ref: '#/components/schemas/user_reference'
      examples:
        by_site:
          summary: Access by site and username
          value:
            - domain: example.com
              username: jsmith
        by_id:
          value:
            - id: 14
          summary: Access by id
        by_other:
          summary: Access by other attributes
          value:
            - middle_name: X.
              last_name: Smith
              comments: Standard user
              first_name: John
  responses:
    ok:
      content:
        application/json:
          schema:
            type: string
      description: |
        ...
paths:
  /users:
    description: |
      A user account ...
    get:
      parameters:
        - description: |
            ...
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/owners_reference_list'
          name: owners_ref
          required: false
          in: query
      responses:
        '200':
          $ref: '#/components/responses/ok'

But if I replace the "examples" attribute with "example", e.g.:

owners_reference_list:
  type: array
  items:
    $ref: '#/components/schemas/user_reference'
  example:
        - domain: example.com
          username: jsmith

then it works fine.

The referenced question is answered that "examples" is supported in Swagger Editor 3.6.21, and the comment by @Helen says that the editor.swagger.io site is using version 3.8.3.

Body:
Schemas do not support multiple examples, they only support a single example.

Multiple examples can only be used in:

request bodies: requestBody.content.<media-type>.examples

responses: responses.<code>.content.<media-type>.examples

parameters that use the content keyword: <parameter>.content.<media-type>.examples


问:
Appending data to JSON file with python?
I have made a small python program which writes some string inputs into a JSON file:

```<code>import json

while True:
    name = input('What is your name?')
    surname = input('What is your surname')
    age = input('How old are you?')

    with open("info_.json", "w") as data:
        information = {name: {'surname': surname, 'age': age}}
        data.write(json.dumps(information))
        data.close()

    with open("info_.json", "r") as info_read:
        dict_info = json.loads(info_read.read())
        name_d = dict_info.get(name)
        print(name_d)
</code>```

It works perfectly fine, althought the second time of the loop, the inputs overwrite the information that was written the first time. Is there any way of adding more data to a file, without overwriting?
Thank you

答:
One does not simply, append into JSON file

You first need to load all JSON data, append to it and write it back.

```<code>import json

json_path = "info_.json"

def write_json(data, filename):
    """Write json file with provided data"""
    with open(filename,'w') as f:
        json.dump(data, f, indent=4)

def print_user_info(name):
    """Read json data file, print specified user"""
    with open(json_path, "r") as info_read:
        info_data = json.loads(info_read.read())
        info_data = dict(info_data)
        user_data = info_data.get(name)
        print(f"{name} : {user_data}")

def update_user_info(name, surname, age):
    """Fetch existing json data, append to it, write to file and print new user details from file"""
    with open(json_path, "r") as info_fp:
        # Read existing data and append to new data it
        info_data = json.load(info_fp)
        info_data[name] = {'surname': surname, 'age': age}

        # Write updated data
        write_json(info_data, filename=json_path)

        # Print new user details from json file
        print_user_info(name)

# Function to take user inputs
def new_user_input():
    """Take user inputs for new user data, update that into json data file"""
    name = input('What is your name? ')
    surname = input('What is your surname? ')
    age = input('How old are you? ')

    update_user_info(name, surname, age)

if __name__ == '__main__':
    new_user_input()
</code>```

Body:
I have made a small python program which writes some string inputs into a JSON file:

import json

while True:
    name = input('What is your name?')
    surname = input('What is your surname')
    age = input('How old are you?')

    with open("info_.json", "w") as data:
        information = {name: {'surname': surname, 'age': age}}
        data.write(json.dumps(information))
        data.close()

    with open("info_.json", "r") as info_read:
        dict_info = json.loads(info_read.read())
        name_d = dict_info.get(name)
        print(name_d)

It works perfectly fine, althought the second time of the loop, the inputs overwrite the information that was written the first time. Is there any way of adding more data to a file, without overwriting?
Thank you

Body:
One does not simply, append into JSON file

You first need to load all JSON data, append to it and write it back.

import json

json_path = "info_.json"

def write_json(data, filename):
    """Write json file with provided data"""
    with open(filename,'w') as f:
        json.dump(data, f, indent=4)

def print_user_info(name):
    """Read json data file, print specified user"""
    with open(json_path, "r") as info_read:
        info_data = json.loads(info_read.read())
        info_data = dict(info_data)
        user_data = info_data.get(name)
        print(f"{name} : {user_data}")

def update_user_info(name, surname, age):
    """Fetch existing json data, append to it, write to file and print new user details from file"""
    with open(json_path, "r") as info_fp:
        # Read existing data and append to new data it
        info_data = json.load(info_fp)
        info_data[name] = {'surname': surname, 'age': age}

        # Write updated data
        write_json(info_data, filename=json_path)

        # Print new user details from json file
        print_user_info(name)

# Function to take user inputs
def new_user_input():
    """Take user inputs for new user data, update that into json data file"""
    name = input('What is your name? ')
    surname = input('What is your surname? ')
    age = input('How old are you? ')

    update_user_info(name, surname, age)

if __name__ == '__main__':
    new_user_input()


问:
Modelling best practices with Grakn
I've looked at how to do data modelling and have some questions in regards to the use of roles specifically in Grakn.

Let's take a simple case. I have a Company, and that Company can be a Distributor, Supplier, Customer, or any such combination. Company A could be a distributor and a customer at the same time.

If I use a relational database, I would have a table for CompanyS and then tables for SupplierS, CustomerS, etc, which then would reference the Company table.

However, I want to start with a Company and know what roles it is playing without having to create these extra tables. So that in my application I can know that a company is both a distributor and a supplier in a single query.

There's a few ways I can think how to do it, but as I feel this problem domain is so common there must be some best practices for modelling these concepts.

So I am looking for common patterns or strategies to model and name certain entity roles. I am using Grakn. Any help is appreciated.

答:
If I understand right, you mean to ask for general rules of thumb for choosing roles. Choosing roles is also caught up in choosing the naming for your relations, entities and attributes. In the case given, company is ubiquitously modelled as an entity, but there are plenty of examples where you may realise that you had the naming for an entity/relation/role mixed up.

Try this for general guidance:

Entity: Should be capable of its own existence in the world. Can be an abstract concept. Use abstract nouns (company, religion), collective nouns, common nouns.

Relation: Should have existence dependent upon the existence of its role players. Use abstract nouns (marriage, membership, hierarchy) and verbal nouns (authorship, ownership, ).

Role: Should describe a behaviour within the context of a relation. You can try using this sentence: A [entity] behaves like a [role] in a [relation]. For example a station behaves like a stop in a train-route. Should use nouns.

Attributes: Should describe a quantity only e.g. name (string), age (long), colour (string), is-green (boolean), verbose (boolean), is-running (boolean), score (double). Typically nouns or verbs. Anything goes if it describes a value well.

If you struggle to find a noun, use a name that ends with a noun, but prepend with a descriptive term, like authored-book.

Title: Modelling best practices with Grakn


问:
My news page in my app isn't retrieving any news and only a blank white page is being displayed instead of a newsfeed
I am currently working on Android Studio 4.0, Build #AI-193.6911.18.40.6514223.

Upon entering the news page, I am being shown a blank page. It appears that the API is not retrieving the news it's supposed to. I've double checked my entire app for any typos (in case it doesn't match the API parameters). Everything appears right but the API is not retrieving the data.

I have attached below the code with respect to the problem.

newspage.java:

```<code>import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.widget.Toast;

import com.example.nvirone.API.ApiClient;
import com.example.nvirone.API.ApiInterface;
import com.example.nvirone.Models.Article;
import com.example.nvirone.Models.News;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class Newspage extends AppCompatActivity {
    public static final String API_KEY = "(unique API key)";
    private RecyclerView recyclerView;
    private Adapter adapter;
    private RecyclerView.LayoutManager layoutManager;
    private List<Article> articles = new ArrayList<>();
    private String TAG = Newspage.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_newspage);
        recyclerView = findViewById(R.id.recyclerView);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new Adapter(articles, Newspage.this);
        recyclerView.setAdapter(adapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setNestedScrollingEnabled(false);
        LoadJson();
    }
public void LoadJson(){
    ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
    String country = Utils.getCountry();

    Call<News> call;
    call = apiInterface.getNews(country, API_KEY);
    call.enqueue(new Callback<News>() {
        @Override
        public void onResponse(Call<News> call, Response<News> response) {
            if (response.isSuccessful() && response.body().getArticle()!=null){
                articles.clear();
                articles = response.body().getArticle();
                adapter.notifyDataSetChanged();
            }
        }

        @Override
        public void onFailure(Call<News> call, Throwable t) {
            Toast.makeText(Newspage.this,"NO result",Toast.LENGTH_LONG).show();
        }
    });
    }
}
</code>```

Newsindetail.java:

```<code>import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class NewInDetail extends AppCompatActivity {
    WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_in_detail);
        Intent intent = getIntent();
        String url = intent.getStringExtra("url");
        webView = findViewById(R.id.webView);
        webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setLoadsImagesAutomatically(true);
        webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl(url);
    }
}
</code>```

Adapter:

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

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.example.nvirone.Models.Article;
import com.squareup.picasso.Picasso;

import java.util.List;

public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {
    private List<Article> articles;
    private Context context;
    private AdapterView.OnItemClickListener OnItemClickListener;
    private OnItemClickListener onItemCLickListener;

    public Adapter(List<Article> articles, Context context) {
        this.articles = articles;
        this.context = context;
    }

    public Adapter() {

    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holders, int position) {
        final MyViewHolder holder = holders;
        final Article model = articles.get(position);
        RequestOptions requestOptions = new RequestOptions();
        requestOptions.placeholder(Utils.getRandomDrawbleColor());
        requestOptions.error(Utils.getRandomDrawbleColor());
        requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL);
        requestOptions.centerCrop();

        Glide.with(context).load(model.getUrlToImage()).apply(requestOptions)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        holder.progressBar.setVisibility(View.GONE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        holder.progressBar.setVisibility(View.GONE);
                        return false;
                    }
                })
                .transition(DrawableTransitionOptions.withCrossFade())
                .into(holder.imageView);
        holder.title.setText(model.getTitle());
        holder.desc.setText(model.getDescription());
        holder.source.setText(model.getSource().getName());
        holder.time.setText('\u2022' + Utils.DateToTimeFormat(model.getPublishedAt()));
        holder.published.setText(Utils.DateToTimeFormat(model.getPublishedAt()));
        holder.author.setText(model.getAuthor());
        String imageURL = model.getUrlToImage();
        Picasso.get().load(imageURL).into(holder.imageView);
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context,NewInDetail.class);
                intent.putExtra("url",model.getUrl());
                context.startActivity(intent);
            }
        });
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item,parent,false);
        return new MyViewHolder(view, onItemCLickListener);
    }

    @Override
    public int getItemCount() {
        return articles.size();
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemCLickListener = onItemClickListener;
    }

    public interface OnItemClickListener{
        void onItemClick(View view, int position);
    }

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

        TextView title, desc, author, published, source, time;
        ImageView imageView;
        ProgressBar progressBar;
        OnItemClickListener onItemClickListener;
        CardView cardView;
        public MyViewHolder(@NonNull View itemView, OnItemClickListener onItemClickListener) {
            super(itemView);
            itemView.setOnClickListener(this);
            title  = itemView.findViewById(R.id.title);
            desc = itemView.findViewById(R.id.desc);
            author = itemView.findViewById(R.id.author);
            published = itemView.findViewById(R.id.publishedAt);
            source = itemView.findViewById(R.id.source);
            time = itemView.findViewById(R.id.time);
            imageView = itemView.findViewById(R.id.img);
            progressBar = itemView.findViewById(R.id.progress_load_photo);
            cardView = itemView.findViewById(R.id.cardView);

            this.onItemClickListener = onItemCLickListener;
        }
        @Override
        public void onClick(View view) {
            onItemClickListener.onItemClick(view, getAdapterPosition());
        }
    }
}
</code>```

ApiClient:

```<code>package com.example.nvirone.API;

import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {
    public static final String BaseURL = "https://newsapi.org/v2/";
    public static Retrofit retrofit ;

    public static Retrofit getApiClient(){
        if(retrofit==null){
            retrofit = new Retrofit.Builder().baseUrl(BaseURL).client(getUnsafeOkHttpClient().build()).addConverterFactory(GsonConverterFactory.create()).build();
        }
        return retrofit;
    }
    public static OkHttpClient.Builder getUnsafeOkHttpClient(){
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            return builder;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
</code>```

ApiInterface:

```<code>package com.example.nvirone.API;

import com.example.nvirone.Models.News;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface ApiInterface {
    @GET("top-headlines")
    Call<News> getNews(

            @Query("country") String country,
            @Query("apiKey") String apiKey
    );
}
</code>```

Utils:

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

import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;

import org.ocpsoft.prettytime.PrettyTime;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;

public class Utils {

    public static ColorDrawable[] vibrantLightColorList =
            {
                    new ColorDrawable(Color.parseColor("#ffeead")),
                    new ColorDrawable(Color.parseColor("#93cfb3")),
                    new ColorDrawable(Color.parseColor("#fd7a7a")),
                    new ColorDrawable(Color.parseColor("#faca5f")),
                    new ColorDrawable(Color.parseColor("#1ba798")),
                    new ColorDrawable(Color.parseColor("#6aa9ae")),
                    new ColorDrawable(Color.parseColor("#ffbf27")),
                    new ColorDrawable(Color.parseColor("#d93947"))
            };

    public static ColorDrawable getRandomDrawbleColor() {
        int idx = new Random().nextInt(vibrantLightColorList.length);
        return vibrantLightColorList[idx];
    }

    public static String DateToTimeFormat(String oldstringDate){
        PrettyTime p = new PrettyTime(new Locale(getCountry()));
        String isTime = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",
                    Locale.ENGLISH);
            Date date = sdf.parse(oldstringDate);
            isTime = p.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return isTime;
    }

    public static String DateFormat(String oldstringDate){
        String newDate;
        SimpleDateFormat dateFormat = new SimpleDateFormat("E, d MMM yyyy", new Locale(getCountry()));
        try {
            Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",Locale.CHINA).parse(oldstringDate);
            assert date != null;
            newDate = dateFormat.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            newDate = oldstringDate;
        }

        return newDate;
    }

    public static String getCountry(){
        Locale locale = Locale.getDefault();
        String country = locale.getCountry();
        return country.toLowerCase();
    }
}
</code>```

Parameters according to the API:

NEWS:

```<code>package com.example.nvirone.Models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import java.util.List;

public class News {
    @SerializedName("status")
    @Expose
    private String status;

    @SerializedName("totalResults")
    @Expose
    private int totalResult;

    @SerializedName("articles")
    @Expose
    private List<Article> article;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public int getTotalResult() {
        return totalResult;
    }

    public void setTotalResult(int totalResult) {
        this.totalResult = totalResult;
    }

    public List<Article> getArticle() {
        return article;
    }

    public void setArticle(List<Article> article) {
        this.article = article;
    }
}
</code>```

Article :

```<code>package com.example.nvirone.Models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Article {
    @SerializedName("source")
    @Expose
    private Source source;

    @SerializedName("author")
    @Expose
    private String author;

    @SerializedName("title")
    @Expose
    private String title;

    @SerializedName("description")
    @Expose
    private String description;

    @SerializedName("url")
    @Expose
    private String url;

    @SerializedName("urlToImage")
    @Expose
    private String urlToImage;

    @SerializedName("publishedAt")
    @Expose
    private String publishedAt;

    public Source getSource() {
        return source;
    }

    public void setSource(Source source) {
        this.source = source;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUrlToImage() {
        return urlToImage;
    }

    public void setUrlToImage(String urlToImage) {
        this.urlToImage = urlToImage;
    }

    public String getPublishedAt() {
        return publishedAt;
    }

    public void setPublishedAt(String publishedAt) {
        this.publishedAt = publishedAt;
    }
}
</code>```

Source:

```<code>package com.example.nvirone.Models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Source {
    @SerializedName("id")
    @Expose
    private String id;

    @SerializedName("name")
    @Expose
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
</code>```

The cardview that is supposed to display the newsfeed :

```<code><?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <androidx.cardview.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="11dp"
        android:layout_marginRight="11dp"
        android:layout_marginTop="7dp"
        android:layout_marginBottom="7dp"
        app:cardElevation="@dimen/cardview_default_elevation"
        app:cardCornerRadius="15dp">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:id="@+id/img"
                android:scaleType="centerCrop"
                android:transitionName="img"
                tools:ignore= "UnusedAttribute"/>
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="80dp"
                android:id="@+id/shadow_bottom"
                android:src="@drawable/bottom_shadow"
                android:layout_alignBottom="@+id/img" />
            <ProgressBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@android:style/Widget.ProgressBar.Small"
                android:id="@+id/progress_load_photo"
                android:layout_marginTop="70dp" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:id="@+id/author"
                android:drawablePadding="10dp"
                android:ellipsize="end"
                android:maxLines="1"
                android:textColor="@android:color/white"
                android:singleLine="true"
                android:text="Author"
                android:gravity="bottom"
                android:layout_marginRight="160dp"
                android:layout_alignLeft="@+id/title"
                android:layout_alignStart="@+id/title"
                android:layout_alignRight="@+id/layoutDate"
                android:layout_alignTop="@+id/layoutDate"
                android:layout_alignEnd="@+id/layoutDate"/>
            <FrameLayout
                android:id="@+id/layoutDate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/img"
                android:background="@drawable/round_white"
                android:padding="5dp"
                android:layout_alignParentRight="true"
                android:layout_marginRight="20dp"
                android:layout_marginTop="50dp">
                <ImageView
                    android:src="@drawable/ic_date"
                    android:layout_width="18dp"
                    android:layout_height="18dp"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"/>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#606060"
                    android:id="@+id/publishedAt"
                    android:layout_marginLeft="27dp"
                    android:layout_marginRight="10dp"
                    android:text="01 January 2000"/>
            </FrameLayout>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fontFamily="sans-serif-light"
                android:textStyle="bold"
                android:textColor="@color/colorTextTitle"
                android:layout_marginLeft="16dp"
                android:layout_marginRight="16dp"
                android:text="Title"
                android:textSize="17sp"
                android:layout_marginTop="10dp"
                android:layout_below="@id/img"
                android:id="@+id/title"/>
            <TextView
                android:id="@+id/desc"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_marginRight="16dp"
                android:layout_below="@+id/title"
                android:layout_marginLeft="16dp"
                android:layout_marginTop="5dp"
                android:text="Desc"/>
            <TextView
                android:id="@+id/source"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_below="@+id/desc"
                android:layout_marginLeft="16dp"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:fontFamily="sans-serif-light"
                android:textStyle="bold"
                android:textColor="@color/colorTextTitle"
                android:ellipsize="end"
                android:singleLine="true"
                android:drawablePadding="10dp"
                android:maxLines="1"
                android:text="Source"/>
            <TextView
                android:id="@+id/time"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_below="@+id/desc"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:layout_toRightOf="@+id/source"
                android:ellipsize="end"
                android:singleLine="true"
                android:drawablePadding="10dp"
                android:maxLines="1"
                android:text="Time"/>

        </RelativeLayout>

    </androidx.cardview.widget.CardView>

</FrameLayout>
</code>```

EDIT :
I have added some code in the API interface as follows and the same problem has come up again after trying to use this query :

```<code>import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class NewInDetail extends AppCompatActivity {
    WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_in_detail);
        Intent intent = getIntent();
        String url = intent.getStringExtra("url");
        webView = findViewById(R.id.webView);
        webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setLoadsImagesAutomatically(true);
        webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl(url);
    }
}
</code>```0

答:
You need to add this method in your Adapter.java:

```<code>public void addArticles(List<Article> articles) {
    this.articles.addAll(articles);
    int count = getItemCount();
    notifyItemRangeInserted(count, count + articles.size());
}
</code>```

And use it this way in your NewsPage.java:

```<code>public void LoadJson() {
   ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
   String       country      = Utils.getCountry();

   Call<News> call;
   call = apiInterface.getNews(country, API_KEY);
   call.enqueue(new Callback<News>() {

      @Override
      public void onResponse(Call<News> call, Response<News> response) {
         List<Article> newArticles = response.body().getArticle();
         if (response.isSuccessful() && newArticles != null) {
            adapter.addArticles(newArticles);
         }
      }

      @Override
      public void onFailure(Call<News> call, Throwable t) {
         Toast.makeText(NewsPage.this, "NO result", Toast.LENGTH_LONG).show();
      }
   });
}
</code>```

Body:
I am currently working on Android Studio 4.0, Build #AI-193.6911.18.40.6514223.

Upon entering the news page, I am being shown a blank page. It appears that the API is not retrieving the news it's supposed to. I've double checked my entire app for any typos (in case it doesn't match the API parameters). Everything appears right but the API is not retrieving the data.

I have attached below the code with respect to the problem.

newspage.java:

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.widget.Toast;

import com.example.nvirone.API.ApiClient;
import com.example.nvirone.API.ApiInterface;
import com.example.nvirone.Models.Article;
import com.example.nvirone.Models.News;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class Newspage extends AppCompatActivity {
    public static final String API_KEY = "(unique API key)";
    private RecyclerView recyclerView;
    private Adapter adapter;
    private RecyclerView.LayoutManager layoutManager;
    private List
 articles = new ArrayList<>();
    private String TAG = Newspage.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_newspage);
        recyclerView = findViewById(R.id.recyclerView);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new Adapter(articles, Newspage.this);
        recyclerView.setAdapter(adapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setNestedScrollingEnabled(false);
        LoadJson();
    }
public void LoadJson(){
    ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
    String country = Utils.getCountry();

    Call<News> call;
    call = apiInterface.getNews(country, API_KEY);
    call.enqueue(new Callback<News>() {
        @Override
        public void onResponse(Call<News> call, Response<News> response) {
            if (response.isSuccessful() && response.body().getArticle()!=null){
                articles.clear();
                articles = response.body().getArticle();
                adapter.notifyDataSetChanged();
            }
        }

        @Override
        public void onFailure(Call<News> call, Throwable t) {
            Toast.makeText(Newspage.this,"NO result",Toast.LENGTH_LONG).show();
        }
    });
    }
}

Newsindetail.java:

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class NewInDetail extends AppCompatActivity {
    WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_in_detail);
        Intent intent = getIntent();
        String url = intent.getStringExtra("url");
        webView = findViewById(R.id.webView);
        webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setLoadsImagesAutomatically(true);
        webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        webView.setWebViewClient(new WebViewClient());
        webView.loadUrl(url);
    }
}

Adapter:

package com.example.nvirone;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.example.nvirone.Models.Article;
import com.squareup.picasso.Picasso;

import java.util.List;

public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {
    private List
 articles;
    private Context context;
    private AdapterView.OnItemClickListener OnItemClickListener;
    private OnItemClickListener onItemCLickListener;

    public Adapter(List
 articles, Context context) {
        this.articles = articles;
        this.context = context;
    }

    public Adapter() {

    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holders, int position) {
        final MyViewHolder holder = holders;
        final Article model = articles.get(position);
        RequestOptions requestOptions = new RequestOptions();
        requestOptions.placeholder(Utils.getRandomDrawbleColor());
        requestOptions.error(Utils.getRandomDrawbleColor());
        requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL);
        requestOptions.centerCrop();

        Glide.with(context).load(model.getUrlToImage()).apply(requestOptions)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        holder.progressBar.setVisibility(View.GONE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        holder.progressBar.setVisibility(View.GONE);
                        return false;
                    }
                })
                .transition(DrawableTransitionOptions.withCrossFade())
                .into(holder.imageView);
        holder.title.setText(model.getTitle());
        holder.desc.setText(model.getDescription());
        holder.source.setText(model.getSource().getName());
        holder.time.setText('\u2022' + Utils.DateToTimeFormat(model.getPublishedAt()));
        holder.published.setText(Utils.DateToTimeFormat(model.getPublishedAt()));
        holder.author.setText(model.getAuthor());
        String imageURL = model.getUrlToImage();
        Picasso.get().load(imageURL).into(holder.imageView);
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context,NewInDetail.class);
                intent.putExtra("url",model.getUrl());
                context.startActivity(intent);
            }
        });
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item,parent,false);
        return new MyViewHolder(view, onItemCLickListener);
    }

    @Override
    public int getItemCount() {
        return articles.size();
    }
    public void setOnItemClickListener(OnItemClickListener onItemClickListener){
        this.onItemCLickListener = onItemClickListener;
    }

    public interface OnItemClickListener{
        void onItemClick(View view, int position);
    }

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

        TextView title, desc, author, published, source, time;
        ImageView imageView;
        ProgressBar progressBar;
        OnItemClickListener onItemClickListener;
        CardView cardView;
        public MyViewHolder(@NonNull View itemView, OnItemClickListener onItemClickListener) {
            super(itemView);
            itemView.setOnClickListener(this);
            title  = itemView.findViewById(R.id.title);
            desc = itemView.findViewById(R.id.desc);
            author = itemView.findViewById(R.id.author);
            published = itemView.findViewById(R.id.publishedAt);
            source = itemView.findViewById(R.id.source);
            time = itemView.findViewById(R.id.time);
            imageView = itemView.findViewById(R.id.img);
            progressBar = itemView.findViewById(R.id.progress_load_photo);
            cardView = itemView.findViewById(R.id.cardView);

            this.onItemClickListener = onItemCLickListener;
        }
        @Override
        public void onClick(View view) {
            onItemClickListener.onItemClick(view, getAdapterPosition());
        }
    }
}

ApiClient:

package com.example.nvirone.API;

import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {
    public static final String BaseURL = "https://newsapi.org/v2/";
    public static Retrofit retrofit ;

    public static Retrofit getApiClient(){
        if(retrofit==null){
            retrofit = new Retrofit.Builder().baseUrl(BaseURL).client(getUnsafeOkHttpClient().build()).addConverterFactory(GsonConverterFactory.create()).build();
        }
        return retrofit;
    }
    public static OkHttpClient.Builder getUnsafeOkHttpClient(){
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            return builder;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

ApiInterface:

package com.example.nvirone.API;

import com.example.nvirone.Models.News;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface ApiInterface {
    @GET("top-headlines")
    Call<News> getNews(

            @Query("country") String country,
            @Query("apiKey") String apiKey
    );
}

Utils:

package com.example.nvirone;

import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;

import org.ocpsoft.prettytime.PrettyTime;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;

public class Utils {

    public static ColorDrawable[] vibrantLightColorList =
            {
                    new ColorDrawable(Color.parseColor("#ffeead")),
                    new ColorDrawable(Color.parseColor("#93cfb3")),
                    new ColorDrawable(Color.parseColor("#fd7a7a")),
                    new ColorDrawable(Color.parseColor("#faca5f")),
                    new ColorDrawable(Color.parseColor("#1ba798")),
                    new ColorDrawable(Color.parseColor("#6aa9ae")),
                    new ColorDrawable(Color.parseColor("#ffbf27")),
                    new ColorDrawable(Color.parseColor("#d93947"))
            };

    public static ColorDrawable getRandomDrawbleColor() {
        int idx = new Random().nextInt(vibrantLightColorList.length);
        return vibrantLightColorList[idx];
    }

    public static String DateToTimeFormat(String oldstringDate){
        PrettyTime p = new PrettyTime(new Locale(getCountry()));
        String isTime = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",
                    Locale.ENGLISH);
            Date date = sdf.parse(oldstringDate);
            isTime = p.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return isTime;
    }

    public static String DateFormat(String oldstringDate){
        String newDate;
        SimpleDateFormat dateFormat = new SimpleDateFormat("E, d MMM yyyy", new Locale(getCountry()));
        try {
            Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",Locale.CHINA).parse(oldstringDate);
            assert date != null;
            newDate = dateFormat.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            newDate = oldstringDate;
        }

        return newDate;
    }

    public static String getCountry(){
        Locale locale = Locale.getDefault();
        String country = locale.getCountry();
        return country.toLowerCase();
    }
}

Parameters according to the API:

NEWS:

package com.example.nvirone.Models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import java.util.List;

public class News {
    @SerializedName("status")
    @Expose
    private String status;

    @SerializedName("totalResults")
    @Expose
    private int totalResult;

    @SerializedName("articles")
    @Expose
    private List
 article;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public int getTotalResult() {
        return totalResult;
    }

    public void setTotalResult(int totalResult) {
        this.totalResult = totalResult;
    }

    public List
 getArticle() {
        return article;
    }

    public void setArticle(List
 article) {
        this.article = article;
    }
}

Article :

package com.example.nvirone.Models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Article {
    @SerializedName("source")
    @Expose
    private Source source;

    @SerializedName("author")
    @Expose
    private String author;

    @SerializedName("title")
    @Expose
    private String title;

    @SerializedName("description")
    @Expose
    private String description;

    @SerializedName("url")
    @Expose
    private String url;

    @SerializedName("urlToImage")
    @Expose
    private String urlToImage;

    @SerializedName("publishedAt")
    @Expose
    private String publishedAt;

    public Source getSource() {
        return source;
    }

    public void setSource(Source source) {
        this.source = source;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUrlToImage() {
        return urlToImage;
    }

    public void setUrlToImage(String urlToImage) {
        this.urlToImage = urlToImage;
    }

    public String getPublishedAt() {
        return publishedAt;
    }

    public void setPublishedAt(String publishedAt) {
        this.publishedAt = publishedAt;
    }
}

Source:

package com.example.nvirone.Models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Source {
    @SerializedName("id")
    @Expose
    private String id;

    @SerializedName("name")
    @Expose
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

The cardview that is supposed to display the newsfeed :

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    <androidx.cardview.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="11dp"
        android:layout_marginRight="11dp"
        android:layout_marginTop="7dp"
        android:layout_marginBottom="7dp"
        app:cardElevation="@dimen/cardview_default_elevation"
        app:cardCornerRadius="15dp">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:id="@+id/img"
                android:scaleType="centerCrop"
                android:transitionName="img"
                tools:ignore= "UnusedAttribute"/>
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="80dp"
                android:id="@+id/shadow_bottom"
                android:src="@drawable/bottom_shadow"
                android:layout_alignBottom="@+id/img" />
            <ProgressBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                style="@android:style/Widget.ProgressBar.Small"
                android:id="@+id/progress_load_photo"
                android:layout_marginTop="70dp" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:id="@+id/author"
                android:drawablePadding="10dp"
                android:ellipsize="end"
                android:maxLines="1"
                android:textColor="@android:color/white"
                android:singleLine="true"
                android:text="Author"
                android:gravity="bottom"
                android:layout_marginRight="160dp"
                android:layout_alignLeft="@+id/title"
                android:layout_alignStart="@+id/title"
                android:layout_alignRight="@+id/layoutDate"
                android:layout_alignTop="@+id/layoutDate"
                android:layout_alignEnd="@+id/layoutDate"/>
            <FrameLayout
                android:id="@+id/layoutDate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/img"
                android:background="@drawable/round_white"
                android:padding="5dp"
                android:layout_alignParentRight="true"
                android:layout_marginRight="20dp"
                android:layout_marginTop="50dp">
                <ImageView
                    android:src="@drawable/ic_date"
                    android:layout_width="18dp"
                    android:layout_height="18dp"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="5dp"/>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#606060"
                    android:id="@+id/publishedAt"
                    android:layout_marginLeft="27dp"
                    android:layout_marginRight="10dp"
                    android:text="01 January 2000"/>
            </FrameLayout>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fontFamily="sans-serif-light"
                android:textStyle="bold"
                android:textColor="@color/colorTextTitle"
                android:layout_marginLeft="16dp"
                android:layout_marginRight="16dp"
                android:text="Title"
                android:textSize="17sp"
                android:layout_marginTop="10dp"
                android:layout_below="@id/img"
                android:id="@+id/title"/>
            <TextView
                android:id="@+id/desc"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_marginRight="16dp"
                android:layout_below="@+id/title"
                android:layout_marginLeft="16dp"
                android:layout_marginTop="5dp"
                android:text="Desc"/>
            <TextView
                android:id="@+id/source"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_below="@+id/desc"
                android:layout_marginLeft="16dp"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:fontFamily="sans-serif-light"
                android:textStyle="bold"
                android:textColor="@color/colorTextTitle"
                android:ellipsize="end"
                android:singleLine="true"
                android:drawablePadding="10dp"
                android:maxLines="1"
                android:text="Source"/>
            <TextView
                android:id="@+id/time"
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_below="@+id/desc"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="10dp"
                android:layout_toRightOf="@+id/source"
                android:ellipsize="end"
                android:singleLine="true"
                android:drawablePadding="10dp"
                android:maxLines="1"
                android:text="Time"/>

        </RelativeLayout>

    </androidx.cardview.widget.CardView>

</FrameLayout>

EDIT :
I have added some code in the API interface as follows and the same problem has come up again after trying to use this query :

@GET("everything")
Call<News> getNewsSearch(

    @Query("q") String Keyword,
    @Query("language") String language,
    @Query("SortBy") String sortBy,
    @Query("apiKey") String apiKey

    );

Body:
You need to add this method in your Adapter.java:

public void addArticles(List<Article> articles) {
    this.articles.addAll(articles);
    int count = getItemCount();
    notifyItemRangeInserted(count, count + articles.size());
}

And use it this way in your NewsPage.java:

public void LoadJson() {
   ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
   String       country      = Utils.getCountry();

   Call<News> call;
   call = apiInterface.getNews(country, API_KEY);
   call.enqueue(new Callback<News>() {

      @Override
      public void onResponse(Call<News> call, Response<News> response) {
         List<Article> newArticles = response.body().getArticle();
         if (response.isSuccessful() && newArticles != null) {
            adapter.addArticles(newArticles);
         }
      }

      @Override
      public void onFailure(Call<News> call, Throwable t) {
         Toast.makeText(NewsPage.this, "NO result", Toast.LENGTH_LONG).show();
      }
   });
}


问:
Dependencies downloader for Android OS
I am taking care of my parents (by the Covid situation) in a place without Internet, not even mobile connectivity. I'm learning Android development and Gradle is requesting an Internet connection to download the dependencies on Android Studio. I only have a desktop computer (without internet), running Linux and a smartphone with Android. I can get Internet on my phone, traveling 20 km to the nearest city without my own car. Is there any tool or mechanism with which I can export the Android project's dependencies to my phone and, after that, connect to the Internet in the city and download the libraries to work with Gradle cache afterwards? I have done something like that before, but from my company with Sonatype Nexus. My PC without having an Internet connection, only connected to the LAN, sets as dependencies the local Maven repositories published in the Nexus, if it do not have the dependencies on the cache, it connect to the Internet and download the library later.</p>

答:
You can download the latest Android Gradle plugin and Google Maven dependencies in your mobile from the URL https://developer.android.com/studio/?gclsrc=aw.ds#downloads and then you can use it to build your projects offline.

Refer https://developer.android.com/studio/intro/studio-config#offline to configure android studio to work without network connection.

Title: Dependencies downloader for Android OS


问:
How to put assert into release builds in C/C++
I need to only run ship build and I need to assert on certain condition in release build to see if the problem is fixed. How do I do it?</p>

答:
The default behaviour of ASSERT is to abort the program under the Debug configuration, but this generally becomes a no-op under a Release configuration.  I believe it does this by checking for the existence of the preprocessor NDEBUG macro.  I'm not at work at the moment so cannot check this.

I think the easiest way around this is to modify the Debug configuration to turn all optimisations up to the same level as Release (O2 from memory), and then re-build your software.  This will give you the equivalent performance and speed of a Release build, but it will still define the NDEBUG preprocessor macro which means all failed ASSERTs will still cause the program to abort.  Just remember to change the optimisation level back later, otherwise you will have trouble debugging under the Debug configuration.

In general though, ASSERTs should only be used for programming preconditions and never to handle failures in shipping software.  You want to fail quickly during development, but gracefully in front of a user.

OwnerDisplayName: pra che

OwnerDisplayName: LeopardSkinPillBoxHat

LastEditorDisplayName: LeopardSkinPillBoxHat


问:
Objective-C, Ads on a scrollview
I'm currently using AdWhirl for my iOS app. I want to have my ads in the bottom of a scrollview. How can I achive that without Interface Builder, or can I use Interface builder?</p>

答:
An initial look suggests that its simply a subclass of UIView. You can get the bounds of your UIScrollView add an instance of the AdWhirl view as a subview to the ScrollView and extend the content area.

Like any other view really.

Title: Objective-C, Ads on a scrollview


问:
What is a good way to maintain a set of constants in Python project?
Have a .py file with below content ?

```<code>class Set1(Enum):
   A = 1
   B = 2

class Set2(Enum):
  hi=1
  hello=2
</code>```

OR simply

```<code>Set1 = {"A":1,"B":2}
Set2 = {"C"="hi","D"="Hello"}
</code>```

Please note that these constants will be used by different modules in the project.

答:
If you have groups of related constants, such as the regex flags, then an Enum is the appropriate tool (e.g. your hi and hello in Set2).

For unrelated constants I would use the Constant class found in aenum1:

```<code>class MiscellaneousConstants(Constant):
    A = 1
    B = 2
</code>```

Constants are similar to Enums in that you cannot rebind them, and they have nice reprs:

```<code>>>> MiscellaneousConstants.A
<MiscellaneousConstants.A: 1>

>>> MiscellaneousConstants.A = 9
Traceback (most recent call last):
  ...
AttributeError: cannot rebind constant <MiscellaneousConstants.A>
</code>```

Typing the class name can be a bother, so to facilitate getting the Constant members into the global name space, export is provided:

```<code>from aenum import Constant, export

@export(globals())
class MiscellaneousConstants(Constant):
    A = 1
    B = 2
</code>```

and in use:

```<code>>>> A
<MiscellaneousConstants.A: 1>
</code>```

Note that, as is normal for Python, names at the global level can still be rebound:

```<code>>>> A = 9
>>> A
9
</code>```

Constant class members, however, are still constant:

```<code>>>> MiscellaneousConstants.A
<MiscellaneousConstants.A: 1>

>>> MiscellaneousConstants.A = 9
Traceback (most recent call last):
  ...
AttributeError: cannot rebind constant <MiscellaneousConstants.A>
</code>```

1 Disclosure:  I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum)  library.

Body:
Have a .py file with below content ?

class Set1(Enum):
   A = 1
   B = 2

class Set2(Enum):
  hi=1
  hello=2

OR simply

Set1 = {"A":1,"B":2}
Set2 = {"C"="hi","D"="Hello"}

Please note that these constants will be used by different modules in the project.

Body:
If you have groups of related constants, such as the regex flags, then an Enum is the appropriate tool (e.g. your hi and hello in Set2).

For unrelated constants I would use the Constant class found in aenum1:

class MiscellaneousConstants(Constant):
    A = 1
    B = 2

Constants are similar to Enums in that you cannot rebind them, and they have nice reprs:

>>> MiscellaneousConstants.A
<MiscellaneousConstants.A: 1>

>>> MiscellaneousConstants.A = 9
Traceback (most recent call last):
  ...
AttributeError: cannot rebind constant <MiscellaneousConstants.A>

Typing the class name can be a bother, so to facilitate getting the Constant members into the global name space, export is provided:

from aenum import Constant, export

@export(globals())
class MiscellaneousConstants(Constant):
    A = 1
    B = 2

and in use:

>>> A
<MiscellaneousConstants.A: 1>

Note that, as is normal for Python, names at the global level can still be rebound:

>>> A = 9
>>> A
9

Constant class members, however, are still constant:

>>> MiscellaneousConstants.A
<MiscellaneousConstants.A: 1>

>>> MiscellaneousConstants.A = 9
Traceback (most recent call last):
  ...
AttributeError: cannot rebind constant <MiscellaneousConstants.A>

1 Disclosure:  I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum)  library.


问:
I need to split .txt file's content to a new line when it sees a backslash
I have a .txt file named "new.txt" and its content is;

```<code>nxy15\nxy995\nxy823\nxy721\nxy1\nxy1872\nxy3482\nxy878\nxy123\nxy8753\nxy1284\nxy4495\nxy4323\nxy812\nxy7123\nxy1273
</code>```

I need to format that .txt file, to be more specific i need to go to the next line when backslash is detected like one number for each line and i need to remove the letters aswell.

Formatted .txt file needs to look like this;

```<code>15
995
823
721
1
1872
...
</code>```

So far, because of my little Java knowledge, i managed to just read the file and output it. Here it is;

```<code>import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ReadingFile{
    public static void main(String[] args) {
        try {
            File file = new File("C:\\new.txt");
            Scanner read = new Scanner(file);
            while (read.hasNextLine()) {
                String obj2 = read.nextLine();
                System.out.println(obj2);
            }
            read.close();
        } catch (FileNotFoundException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }
    }
}
</code>```

I need to solve this so i can move on to the next question but i'm stuck with this question and can't solve it and i'm trying for three hours.

Any help or clues are highly appreciated, thanks.

Body:
I have a .txt file named "new.txt" and its content is;

nxy15\nxy995\nxy823\nxy721\nxy1\nxy1872\nxy3482\nxy878\nxy123\nxy8753\nxy1284\nxy4495\nxy4323\nxy812\nxy7123\nxy1273

I need to format that .txt file, to be more specific i need to go to the next line when backslash is detected like one number for each line and i need to remove the letters aswell.

Formatted .txt file needs to look like this;

15
995
823
721
1
1872
...

So far, because of my little Java knowledge, i managed to just read the file and output it. Here it is;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ReadingFile{
    public static void main(String[] args) {
        try {
            File file = new File("C:\\new.txt");
            Scanner read = new Scanner(file);
            while (read.hasNextLine()) {
                String obj2 = read.nextLine();
                System.out.println(obj2);
            }
            read.close();
        } catch (FileNotFoundException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }
    }
}

I need to solve this so i can move on to the next question but i'm stuck with this question and can't solve it and i'm trying for three hours.

Any help or clues are highly appreciated, thanks.

Body:
Try like this:

String s = "nxy15\nxy995\nxy823\nxy721\nxy1\nxy1872\nxy3482\nxy878\nxy123\nxy8753\nxy1284\nxy4495\nxy4323\nxy812\nxy7123\nxy1273";
String[]s1 = s.split("[\\\\]+");
for(String s2:s1) {
    System.out.println(s2.replaceAll("[A-Za-z]", ""));
}

You'll get:

15
995
823
721
1
1872
3482
878
123
8753
1284
4495
4323
812
7123
1273