QUIC 프로토콜을 사용하여 알림을 만들 때 사용[Kotlin]
Las características clave de QUIC 아들:
Algunas empresas están comenzando a accir QUIC en sus servidores, ahora desde el lado del cliente, es hora de estar preparados y agregar soporte QUIC a nuestras aplicaciones. Esta vez construiremos una aplicación de noticias con soporte QUIC usando el kit HQUIC.
HQUIC nos permite conectarnos con servicios web a través del protocolo QUIC, si el control remoto no es compatible con QUIC, el kit usará HTTP 2 en su lugar automáticamente.
요구 사항 사전
Agregar las Dependencias requeridas
Este ejemplo requerirá las siguientes Dependencias:
HQUIC는 Huawei가 우수한 build.gradle을 사용하여 Agregar el repositorio를 사용할 수 있도록 합니다.
buildscript {
buildscript {
repositories {
maven { url 'https://developer.huawei.com/repo/' }// This line
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
}
}
}
allprojects {
repositories {
maven { url 'https://developer.huawei.com/repo/' }// and this one
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Ahora agregue las dependsencias requeridas a nivel de aplicación build.gradle
implementation 'com.huawei.hms:hquic-provider:5.0.0.300'
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
디세난도 라 UI
대부분의 목록은 RecyclerView의 요소 목록에 포함되어 있으며, 요소를 제거하기 위해 요소를 준비하는 데 사용됩니다. Esta vista básica solo mostrará el título, una breve introducción y la fecha de publicación:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="TextView"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="Content"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" />
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/content" />
</androidx.constraintlayout.widget.ConstraintLayout>
Para el diseño de la actividad, el diseño contendrá un SwipeRefresLayout con el RecyclerView dentro
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/swipeRefreshLayout">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerNews"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</FrameLayout>
Para mostrar los artículos en una vista de reciclador, necesitarás un adaptador, el adaptador informará el evento de clic de cualquier elemento al oyente dado.
class NewsAdapter(val news:ArrayList<Article>,var listener: NewsViewHolder.onNewsClickListener?): RecyclerView.Adapter<NewsAdapter.NewsViewHolder>() {
class NewsViewHolder(itemView: View, var listener:onNewsClickListener?) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
public fun init(article: Article){
itemView.title.text=article.title
itemView.content.text=article.description
val date= SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault()).parse(article.time)
itemView.time.text=date?.toString()
itemView.setOnClickListener(this)
}
interface onNewsClickListener{
fun onClickedArticle(position: Int)
}
override fun onClick(v: View?) {
listener?.onClickedArticle(adapterPosition)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder {
val view=LayoutInflater.from(parent.context)
.inflate(R.layout.item_view,parent,false)
return NewsViewHolder(view,listener)
}
override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
holder.init(news[position])
}
override fun getItemCount(): Int {
return news.size
}
}
HQUIC 서비스
Usaremos la clase HQUICService는 HQUIC의 데모를 보여주기 위해 사용됩니다. Esta clase abstrae las capacidades del kit HQUIC y nos permite realizar una solicitud fácilmente.
class HQUICService (val context: Context){
private val TAG = "HQUICService"
private val DEFAULT_PORT = 443
private val DEFAULT_ALTERNATEPORT = 443
private val executor: Executor = Executors.newSingleThreadExecutor()
private var cronetEngine: CronetEngine? = null
private var callback: UrlRequest.Callback? = null
/**
* Asynchronous initialization.
*/
init {
HQUICManager.asyncInit(
context,
object : HQUICManager.HQUICInitCallback {
override fun onSuccess() {
Log.i(TAG, "HQUICManager asyncInit success")
}
override fun onFail(e: Exception?) {
Log.w(TAG, "HQUICManager asyncInit fail")
}
})
}
/**
* Create a Cronet engine.
*
* @param url URL.
* @return cronetEngine Cronet engine.
*/
private fun createCronetEngine(url: String): CronetEngine? {
if (cronetEngine != null) {
return cronetEngine
}
val builder= CronetEngine.Builder(context)
builder.enableQuic(true)
builder.addQuicHint(getHost(url), DEFAULT_PORT, DEFAULT_ALTERNATEPORT)
cronetEngine = builder.build()
return cronetEngine
}
/**
* Construct a request
*
* @param url Request URL.
* @param method method Method type.
* @return UrlRequest urlrequest instance.
*/
private fun builRequest(url: String, method: String): UrlRequest? {
val cronetEngine: CronetEngine? = createCronetEngine(url)
val requestBuilder= cronetEngine?.newUrlRequestBuilder(url, callback, executor)
requestBuilder?.apply {
setHttpMethod(method)
return build()
}
return null
}
/**
* Send a request to the URL.
*
* @param url Request URL.
* @param method Request method type.
*/
fun sendRequest(url: String, method: String) {
Log.i(TAG, "callURL: url is " + url + "and method is " + method)
val urlRequest: UrlRequest? = builRequest(url, method)
urlRequest?.apply { urlRequest.start() }
}
/**
* Parse the domain name to obtain the host name.
*
* @param url Request URL.
* @return host Host name.
*/
private fun getHost(url: String): String? {
var host: String? = null
try {
val url1 = URL(url)
host = url1.host
} catch (e: MalformedURLException) {
Log.e(TAG, "getHost: ", e)
}
return host
}
fun setCallback(mCallback: UrlRequest.Callback?) {
callback = mCallback
}
}
Descargando las 알림
Definiremos una clase auxiliar para manejar la solicitud y analiza la respuesta en una ArrayList. El kit HQUIC leerá una cierta cantidad de bytes por vez, para respuestas grandes, el método onReadCompleted se llamará más de una vez.
data class Article(val author:String,
val title:String,
val description:String,
val url:String,
val time:String)
class NewsClient(context: Context): UrlRequest.Callback() {
var hquicService: HQUICService? = null
val CAPACITY = 10240
val TAG="NewsDownloader"
var response:StringBuilder=java.lang.StringBuilder()
var listener:NewsClientListener?=null
init {
hquicService = HQUICService(context)
hquicService?.setCallback(this)
}
fun getNews(url: String, method:String){
hquicService?.sendRequest(url,method)
}
override fun onRedirectReceived(
request: UrlRequest,
info: UrlResponseInfo,
newLocationUrl: String
) {
request.followRedirect()
}
override fun onResponseStarted(request: UrlRequest, info: UrlResponseInfo) {
Log.i(TAG, "onResponseStarted: ")
val byteBuffer = ByteBuffer.allocateDirect(CAPACITY)
request.read(byteBuffer)
}
override fun onReadCompleted(
request: UrlRequest,
info: UrlResponseInfo,
byteBuffer: ByteBuffer
) {
Log.i(TAG, "onReadCompleted: method is called")
val readed=String(byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.position())
response.append(readed)
request.read(ByteBuffer.allocateDirect(CAPACITY))
}
override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
//If everything is ok you can read the response body
val json=JSONObject(response.toString())
val array=json.getJSONArray("articles")
val list=ArrayList<Article>()
for (i in 0 until array.length()){
val article=array.getJSONObject(i)
val author=article.getString("author")
val title=article.getString("title")
val description=article.getString("description")
val time=article.getString("publishedAt")
val url=article.getString("url")
list.add(Article(author, title, description, url, time))
}
listener?.onSuccess(list)
}
override fun onFailed(request: UrlRequest, info: UrlResponseInfo, error: CronetException) {
//If someting fails you must report the error
listener?.onFailure(error.toString())
}
public interface NewsClientListener{
fun onSuccess(news:ArrayList<Article>)
fun onFailure(error: String)
}
}
Haciendo la solicitud
Definir propiedades de solicitud.
private val API_KEY="YOUR_API_KEY"
private val URL = "https://newsapi.org/v2/top-headlines?apiKey=$API_KEY"
private val METHOD = "GET"
Llama a la función getNews para iniciar la solicitud, si todo va bien, la lista de noticias se entregará en la devolución de llamada onSuccess. 오류가 발생하면 장애 시 발전량을 활성화하십시오.
private fun getNews() {
val country=Locale.getDefault().country
val url= "$URL&country=$country"
Log.e("URL",url)
val downloader=NewsClient(this)
downloader.apply {
listener=this@MainActivity
getNews(url,METHOD)
}
}
override fun onSuccess(news: ArrayList<Article>) {
this.news.apply {
clear()
addAll(news)
}
runOnUiThread{
swipeRefreshLayout.isRefreshing=false
loadingDialog?.dismiss()
adapter?.notifyDataSetChanged()
}
}
override fun onFailure(error: String) {
val errorDialog=AlertDialog.Builder(this).apply {
setTitle(R.string.error_title)
val message="${getString(R.string.error_message)} \n $error"
setMessage(message)
setPositiveButton(R.string.ok){ dialog, _ ->
dialog.dismiss()
}
setCancelable(false)
create()
show()
}
}
결론
Es solo cuestión de tiempo para que el protocolo QUIC se convierta en el nuevo estándar de conexiones a Internet. Por ahora, puedes preparar tus aplicaciones para accidirlo y brindar la mejor experiencia de usuario.
Prueba 엘 데모: https://github.com/danms07/HQUICNews
Les compartimos el link al articulo 원본
https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0202352465220930189&fid=0101187876626530001
Reference
이 문제에 관하여(QUIC 프로토콜을 사용하여 알림을 만들 때 사용[Kotlin]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/huaweidevslatam/creacion-de-una-aplicacion-de-noticias-utilizando-el-protocolo-quic-kotlin-1g9
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="TextView"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="Content"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" />
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/content" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="@+id/swipeRefreshLayout">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerNews"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</FrameLayout>
class NewsAdapter(val news:ArrayList<Article>,var listener: NewsViewHolder.onNewsClickListener?): RecyclerView.Adapter<NewsAdapter.NewsViewHolder>() {
class NewsViewHolder(itemView: View, var listener:onNewsClickListener?) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
public fun init(article: Article){
itemView.title.text=article.title
itemView.content.text=article.description
val date= SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault()).parse(article.time)
itemView.time.text=date?.toString()
itemView.setOnClickListener(this)
}
interface onNewsClickListener{
fun onClickedArticle(position: Int)
}
override fun onClick(v: View?) {
listener?.onClickedArticle(adapterPosition)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder {
val view=LayoutInflater.from(parent.context)
.inflate(R.layout.item_view,parent,false)
return NewsViewHolder(view,listener)
}
override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
holder.init(news[position])
}
override fun getItemCount(): Int {
return news.size
}
}
Usaremos la clase HQUICService는 HQUIC의 데모를 보여주기 위해 사용됩니다. Esta clase abstrae las capacidades del kit HQUIC y nos permite realizar una solicitud fácilmente.
class HQUICService (val context: Context){
private val TAG = "HQUICService"
private val DEFAULT_PORT = 443
private val DEFAULT_ALTERNATEPORT = 443
private val executor: Executor = Executors.newSingleThreadExecutor()
private var cronetEngine: CronetEngine? = null
private var callback: UrlRequest.Callback? = null
/**
* Asynchronous initialization.
*/
init {
HQUICManager.asyncInit(
context,
object : HQUICManager.HQUICInitCallback {
override fun onSuccess() {
Log.i(TAG, "HQUICManager asyncInit success")
}
override fun onFail(e: Exception?) {
Log.w(TAG, "HQUICManager asyncInit fail")
}
})
}
/**
* Create a Cronet engine.
*
* @param url URL.
* @return cronetEngine Cronet engine.
*/
private fun createCronetEngine(url: String): CronetEngine? {
if (cronetEngine != null) {
return cronetEngine
}
val builder= CronetEngine.Builder(context)
builder.enableQuic(true)
builder.addQuicHint(getHost(url), DEFAULT_PORT, DEFAULT_ALTERNATEPORT)
cronetEngine = builder.build()
return cronetEngine
}
/**
* Construct a request
*
* @param url Request URL.
* @param method method Method type.
* @return UrlRequest urlrequest instance.
*/
private fun builRequest(url: String, method: String): UrlRequest? {
val cronetEngine: CronetEngine? = createCronetEngine(url)
val requestBuilder= cronetEngine?.newUrlRequestBuilder(url, callback, executor)
requestBuilder?.apply {
setHttpMethod(method)
return build()
}
return null
}
/**
* Send a request to the URL.
*
* @param url Request URL.
* @param method Request method type.
*/
fun sendRequest(url: String, method: String) {
Log.i(TAG, "callURL: url is " + url + "and method is " + method)
val urlRequest: UrlRequest? = builRequest(url, method)
urlRequest?.apply { urlRequest.start() }
}
/**
* Parse the domain name to obtain the host name.
*
* @param url Request URL.
* @return host Host name.
*/
private fun getHost(url: String): String? {
var host: String? = null
try {
val url1 = URL(url)
host = url1.host
} catch (e: MalformedURLException) {
Log.e(TAG, "getHost: ", e)
}
return host
}
fun setCallback(mCallback: UrlRequest.Callback?) {
callback = mCallback
}
}
Descargando las 알림
Definiremos una clase auxiliar para manejar la solicitud y analiza la respuesta en una ArrayList. El kit HQUIC leerá una cierta cantidad de bytes por vez, para respuestas grandes, el método onReadCompleted se llamará más de una vez.
data class Article(val author:String,
val title:String,
val description:String,
val url:String,
val time:String)
class NewsClient(context: Context): UrlRequest.Callback() {
var hquicService: HQUICService? = null
val CAPACITY = 10240
val TAG="NewsDownloader"
var response:StringBuilder=java.lang.StringBuilder()
var listener:NewsClientListener?=null
init {
hquicService = HQUICService(context)
hquicService?.setCallback(this)
}
fun getNews(url: String, method:String){
hquicService?.sendRequest(url,method)
}
override fun onRedirectReceived(
request: UrlRequest,
info: UrlResponseInfo,
newLocationUrl: String
) {
request.followRedirect()
}
override fun onResponseStarted(request: UrlRequest, info: UrlResponseInfo) {
Log.i(TAG, "onResponseStarted: ")
val byteBuffer = ByteBuffer.allocateDirect(CAPACITY)
request.read(byteBuffer)
}
override fun onReadCompleted(
request: UrlRequest,
info: UrlResponseInfo,
byteBuffer: ByteBuffer
) {
Log.i(TAG, "onReadCompleted: method is called")
val readed=String(byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.position())
response.append(readed)
request.read(ByteBuffer.allocateDirect(CAPACITY))
}
override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
//If everything is ok you can read the response body
val json=JSONObject(response.toString())
val array=json.getJSONArray("articles")
val list=ArrayList<Article>()
for (i in 0 until array.length()){
val article=array.getJSONObject(i)
val author=article.getString("author")
val title=article.getString("title")
val description=article.getString("description")
val time=article.getString("publishedAt")
val url=article.getString("url")
list.add(Article(author, title, description, url, time))
}
listener?.onSuccess(list)
}
override fun onFailed(request: UrlRequest, info: UrlResponseInfo, error: CronetException) {
//If someting fails you must report the error
listener?.onFailure(error.toString())
}
public interface NewsClientListener{
fun onSuccess(news:ArrayList<Article>)
fun onFailure(error: String)
}
}
Haciendo la solicitud
Definir propiedades de solicitud.
private val API_KEY="YOUR_API_KEY"
private val URL = "https://newsapi.org/v2/top-headlines?apiKey=$API_KEY"
private val METHOD = "GET"
Llama a la función getNews para iniciar la solicitud, si todo va bien, la lista de noticias se entregará en la devolución de llamada onSuccess. 오류가 발생하면 장애 시 발전량을 활성화하십시오.
private fun getNews() {
val country=Locale.getDefault().country
val url= "$URL&country=$country"
Log.e("URL",url)
val downloader=NewsClient(this)
downloader.apply {
listener=this@MainActivity
getNews(url,METHOD)
}
}
override fun onSuccess(news: ArrayList<Article>) {
this.news.apply {
clear()
addAll(news)
}
runOnUiThread{
swipeRefreshLayout.isRefreshing=false
loadingDialog?.dismiss()
adapter?.notifyDataSetChanged()
}
}
override fun onFailure(error: String) {
val errorDialog=AlertDialog.Builder(this).apply {
setTitle(R.string.error_title)
val message="${getString(R.string.error_message)} \n $error"
setMessage(message)
setPositiveButton(R.string.ok){ dialog, _ ->
dialog.dismiss()
}
setCancelable(false)
create()
show()
}
}
결론
Es solo cuestión de tiempo para que el protocolo QUIC se convierta en el nuevo estándar de conexiones a Internet. Por ahora, puedes preparar tus aplicaciones para accidirlo y brindar la mejor experiencia de usuario.
Prueba 엘 데모: https://github.com/danms07/HQUICNews
Les compartimos el link al articulo 원본
https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0202352465220930189&fid=0101187876626530001
Reference
이 문제에 관하여(QUIC 프로토콜을 사용하여 알림을 만들 때 사용[Kotlin]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/huaweidevslatam/creacion-de-una-aplicacion-de-noticias-utilizando-el-protocolo-quic-kotlin-1g9
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
data class Article(val author:String,
val title:String,
val description:String,
val url:String,
val time:String)
class NewsClient(context: Context): UrlRequest.Callback() {
var hquicService: HQUICService? = null
val CAPACITY = 10240
val TAG="NewsDownloader"
var response:StringBuilder=java.lang.StringBuilder()
var listener:NewsClientListener?=null
init {
hquicService = HQUICService(context)
hquicService?.setCallback(this)
}
fun getNews(url: String, method:String){
hquicService?.sendRequest(url,method)
}
override fun onRedirectReceived(
request: UrlRequest,
info: UrlResponseInfo,
newLocationUrl: String
) {
request.followRedirect()
}
override fun onResponseStarted(request: UrlRequest, info: UrlResponseInfo) {
Log.i(TAG, "onResponseStarted: ")
val byteBuffer = ByteBuffer.allocateDirect(CAPACITY)
request.read(byteBuffer)
}
override fun onReadCompleted(
request: UrlRequest,
info: UrlResponseInfo,
byteBuffer: ByteBuffer
) {
Log.i(TAG, "onReadCompleted: method is called")
val readed=String(byteBuffer.array(), byteBuffer.arrayOffset(), byteBuffer.position())
response.append(readed)
request.read(ByteBuffer.allocateDirect(CAPACITY))
}
override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
//If everything is ok you can read the response body
val json=JSONObject(response.toString())
val array=json.getJSONArray("articles")
val list=ArrayList<Article>()
for (i in 0 until array.length()){
val article=array.getJSONObject(i)
val author=article.getString("author")
val title=article.getString("title")
val description=article.getString("description")
val time=article.getString("publishedAt")
val url=article.getString("url")
list.add(Article(author, title, description, url, time))
}
listener?.onSuccess(list)
}
override fun onFailed(request: UrlRequest, info: UrlResponseInfo, error: CronetException) {
//If someting fails you must report the error
listener?.onFailure(error.toString())
}
public interface NewsClientListener{
fun onSuccess(news:ArrayList<Article>)
fun onFailure(error: String)
}
}
Definir propiedades de solicitud.
private val API_KEY="YOUR_API_KEY"
private val URL = "https://newsapi.org/v2/top-headlines?apiKey=$API_KEY"
private val METHOD = "GET"
Llama a la función getNews para iniciar la solicitud, si todo va bien, la lista de noticias se entregará en la devolución de llamada onSuccess. 오류가 발생하면 장애 시 발전량을 활성화하십시오.
private fun getNews() {
val country=Locale.getDefault().country
val url= "$URL&country=$country"
Log.e("URL",url)
val downloader=NewsClient(this)
downloader.apply {
listener=this@MainActivity
getNews(url,METHOD)
}
}
override fun onSuccess(news: ArrayList<Article>) {
this.news.apply {
clear()
addAll(news)
}
runOnUiThread{
swipeRefreshLayout.isRefreshing=false
loadingDialog?.dismiss()
adapter?.notifyDataSetChanged()
}
}
override fun onFailure(error: String) {
val errorDialog=AlertDialog.Builder(this).apply {
setTitle(R.string.error_title)
val message="${getString(R.string.error_message)} \n $error"
setMessage(message)
setPositiveButton(R.string.ok){ dialog, _ ->
dialog.dismiss()
}
setCancelable(false)
create()
show()
}
}
결론
Es solo cuestión de tiempo para que el protocolo QUIC se convierta en el nuevo estándar de conexiones a Internet. Por ahora, puedes preparar tus aplicaciones para accidirlo y brindar la mejor experiencia de usuario.
Prueba 엘 데모: https://github.com/danms07/HQUICNews
Les compartimos el link al articulo 원본
https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0202352465220930189&fid=0101187876626530001
Reference
이 문제에 관하여(QUIC 프로토콜을 사용하여 알림을 만들 때 사용[Kotlin]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/huaweidevslatam/creacion-de-una-aplicacion-de-noticias-utilizando-el-protocolo-quic-kotlin-1g9
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(QUIC 프로토콜을 사용하여 알림을 만들 때 사용[Kotlin]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/huaweidevslatam/creacion-de-una-aplicacion-de-noticias-utilizando-el-protocolo-quic-kotlin-1g9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)